[Java] 객체 지향 프로그래밍 개념 정리

LeeSeungEun·2023년 5월 9일
0

JAVA

목록 보기
2/28

1. 남의 클래스 & 남의 인스턴스 개념

  • FileWiter라는 클래스를 복제하여 f1이라는 변수에 담는다.
  • f1에는 filewiter를 복제한 filewriter의 인스턴스가 생긴다.
  • 그 인스턴스 메소드를 호출하는 것을 통해 인스턴스를 조작 가능하다.
import java.io.FileWriter;
import java.io.IOException;

public class Hello {
    public static void main(String[] args) throws IOException {
        // class : System, Math, FileWriter
        // instance : f1, f2

        System.out.println(Math.PI);
        System.out.println(Math.floor(1.8));

        FileWriter f1 =  new FileWriter("data.txt"); // data.txt는 수정하고자 하는 파일의 이름 , 수정하고자 하는 파일의 대상이 반드시 지정 되어야함, 이를 누락하지 않도록 인스턴스를 생성하는 시점에 파일 이름을 지정할 수 있다면 안전하게 코드 생성 할 수 있음, 따라서 생성자와 this 개념 나옴
        f1.write("Hello");
        f1.write(" Java");
        f1.close();

    }
}

2. 변수 & 메소드


import java.util.Scanner;

public class Hello {
    public static void main(String[] args) {
        // 방법 1
        printA("--");
        printA("--");
        printB("--");
        printB("--");

        printA("**");
        printA("**");
        printB("**");
        printB("**");
    }

        public static void printA (String delimiter) {
            System.out.println(delimiter);
            System.out.println("A");
            System.out.println("A");
        }

        public static void printB (String delimiter) {
            System.out.println(delimiter);
            System.out.println("B");
            System.out.println("B");
        }
}

import java.util.Scanner;

public class Hello {
    public static void main(String[] args) {
        // 방법 2 (변수정의)
        String delimiter = "--";
        printA(delimiter);
        printA(delimiter);
        printB(delimiter);
        printB(delimiter);

        delimiter = "**";
        printA(delimiter);
        printA(delimiter);
        printB(delimiter);
        printB(delimiter);
    }

        public static void printA (String delimiter) {
            System.out.println(delimiter);
            System.out.println("A");
            System.out.println("A");
        }

        public static void printB (String delimiter) {
            System.out.println(delimiter);
            System.out.println("B");
            System.out.println("B");
        }
}

import java.util.Scanner;

public class Hello {

    public static String delimiter = "";
    public static void main(String[] args) {
        // 방법 3
        // 메소드 안에서 정의 된 변수는 안에서만 사용 가능, 따라서 hello 클래스의 소속인 변수를 생성
        delimiter = "--";
        printA();
        printA();
        printB();
        printB();

        delimiter = "**";
        printA();
        printA();
        printB();
        printB();
    }

        public static void printA () {
            System.out.println(delimiter);
            System.out.println("A");
            System.out.println("A");
        }

        public static void printB () {
            System.out.println(delimiter);
            System.out.println("B");
            System.out.println("B");
        }
}

3. 클래스 - 존재 이유와 기본 형식


import java.util.Scanner;
class print {
    public static String delimiter = "";
    public static void A () {
        System.out.println(delimiter);
        System.out.println("A");
        System.out.println("A");
    }

    public static void B () {
        System.out.println(delimiter);
        System.out.println("B");
        System.out.println("B");
    }
}
public class Hello {
    public static void main(String[] args) {
        // 방법 4 (클래스)
        print.delimiter = "--";
        print.A();
        print.A();
        print.B();
        print.B();

        print.delimiter = "**";
        print.A();
        print.A();
        print.B();
        print.B();
    }
}

4. 나의 인스턴스

  • class를 복제하여 instance를 생성한다.
import java.util.Scanner;
class print {
    public String delimiter = ""; // Print p1 = new print();를 적으면서 static을 삭제함 (static이 클래스의 소속이였으나 인스턴스의 소속으로 만들어주기 위해
    public void A () { // 위와 같은 이유로 print.A()에서 p1.A();로 바꾸면서 static 삭제
        System.out.println(delimiter);
        System.out.println("A");
        System.out.println("A");
    }

    public void B () {
        System.out.println(delimiter);
        System.out.println("B");
        System.out.println("B");
    }
}
public class Hello {
    public static void main(String[] args) {
        // 방법 5 (인스턴스)
        print p1 = new print();
        p1.delimiter = "--"; // 이것을 지정 해주지 않으면 우리가 만든 클래스가 인스턴스화 되지 않도록 한다면 사용자가 안전한 코드를 생성 할 수 있음, 이를 위해 생성자와 this 개념 나옴
        p1.A();
        p1.A();
        p1.B();
        p1.B();

        print p2 = new print();
        p2.delimiter = "**";
        p2.A();
        p2.A();
        p2.B();
        p2.B();

    }
}
  • 클래스 : 변수와 메소드를 내가 필요한것들로 정해놓은 묶어 놓은 도구
  • 인스터스 : 클래스를 내가 원하는대로 지정해놓은것들을 복제 시킨뒤 클래스에다 지정해놓은 것들은 조금씩만 변형시켜서 다시 쓸수 있게 해주는 묶음

5. static

import java.util.Scanner;
class Foo {
    public static String classVar = "I class var";
    public String instanceVar = "I instance var";
    public static void classMethod() {
        System.out.println(classVar);
        // System.out.println(instanceVar); Error
    }
    public void instanceMethod () {
        System.out.println(classVar);
        System.out.println(instanceVar);
    }
}
public class Hello {
    public static void main(String[] args) {
        System.out.println(Foo.classVar); // 클래스를 통해서 클레스 변수
        // System.out.println(Foo.instanceVar); // Error 인스턴스를 통해 변수 접근 가능
        Foo.classMethod(); // 클래스 소속이라 호출 됨
        // Foo.instanceMethod() ; // error 인스턴스 메소드는 인스턴스 소속이라 클래스 통해 접근 불가
        // 결론 : 클래스를 통해 인스턴스 변수 접근 불가, 인스턴스 메소드 접근도 불가
        /*
        static String classVar = " I class var"
        String instanceVar = "I instance var" (불가)
        static classMethod(){}
        instanceMethod(){} (불가)
         */
        Foo f1 = new Foo(); // 인스턴스 생성
        Foo f2 = new Foo();

        System.out.println(f1.classVar); // I class var
        System.out.println(f1.instanceVar); // I instance var

        f1.classVar = "changed by f1";
        System.out.println(Foo.classVar); // changed by f1
        System.out.println(f2.classVar); // changed by f1

        f1.instanceVar = "changed by f1";
        System.out.println(f1.instanceVar); // changed by f1
        System.out.println(f2.instanceVar); // I instance var
        //System.out.println(Foo.instanceVar); error
    }
}
  • f1은 실제 값을 갖지 않고 foo 값을 가리킬뿐 , 링크되어 있어 값을 한쪽에서 바꾸면 둘다 변경 된다.
  • foo에서 f1이라는 인스턴스가 생성 될 때 instancevar라는 변수가 생성되면서 만약 클래스 값이 셋팅 되어 있다면 그 값까지 복제가 되며, 링크되어 있지 않아 f1의 값을 바꾼다고 foo 값이 바뀌지 않는다.
  • 클래스의 변수 값을 바꾸면 모든 인스턴스 값이 바뀐다. (f2값을 바꿔도 class와 f1 모두 바뀜

6. 생성자와 this

import java.util.Scanner;
class print {
    public String delimiter = ""; // this 가 가르키는 delimiter
    public print(String delimiter) { // 생성자 (static이나 리턴타입 지정하지 않음)
        this.delimiter = delimiter; // this는 생성한 인스턴스 이름
    }
    public void A () {
        System.out.println(delimiter); // 해당 코드를 더 명확히 하기 위해서는 this.delimiter가 올바름
        System.out.println("A");
        System.out.println("A");
    }

    public void B () {
        System.out.println(delimiter);
        System.out.println("B");
        System.out.println("B");
    }
}
public class Hello {
    public static void main(String[] args) {
        // 방법 5 (인스턴스)
        print p1 = new print("--"); // 클래스와 똑같은 이름의 메소드를 정의하면 이것이 바로 생성자, 인스턴스를 생성 할 때 클래스와 동일한 이름의 메소드가 있다면 그 메소드를 호출하도록 약속 되어 있음, 그 클래스가 인스턴스화 될 때 실행되어야할 코드를 생성자 메소드 안에 정의함으로써 초기화의 목적을 달성할 수 있음
        /*
        print p1 = new print();
        p1.delimiter = "--"; // 이것을 지정 해주지 않으면 우리가 만든 클래스가 인스턴스화 되지 않도록 한다면 사용자가 안전한 코드를 생성 할 수 있음, 이를 위해 생성자와 this 개념 나옴
         */
        p1.A();

        // 생성자 : 초기에 주입할 필요가 있는 값을 전달하거나 초기의 작업을 수행하기 위해 사용
        // this : 클래스가 인스턴스화 되었을 떄 인스턴스를 가르키기 위한 특수한 이름

    }
}

7. 클래스화 활용

// 클래스화 전
public class Hello {
    // 공급가액
    public static double valueOfSupply;
    // 부가가치세율
    public static double vatRate = 0.1;

    public static double getVAT() {
        return valueOfSupply * vatRate;
    }

    public static double getTotal() {
        return valueOfSupply + getVAT();
    }

    public static void main(String[] args) {
        valueOfSupply = 10000.0;
        System.out.println("Value of supply : " + valueOfSupply);
        System.out.println("VAT : " + getVAT());
        System.out.println("Total : " + getTotal());

    }

}
// 클래스화 후
class Accounting {
    // 공급가액
    public static double valueOfSupply;
    // 부가가치세율
    public static double vatRate = 0.1;

    public static double getVAT() {
        return valueOfSupply * vatRate;
    }

    public static double getTotal() {
        return valueOfSupply + getVAT();
    }

}

public class Hello {
    public static void main(String[] args) {
        Accounting.valueOfSupply = 10000.0;
        System.out.println("Value of supply : " +  Accounting.valueOfSupply);
        System.out.println("VAT : " + Accounting.getVAT());
        System.out.println("Total : " + Accounting.getTotal());

    }

}

8. 인스턴스 화

  • 공급가액이 1만원이라고 setting 되면 부가가치세,총액 얼마인지 확인이 필요한다면 그냥 클래스를 사용 하면 된다.
  • 그리고 만원 셋팅 후 만원과 관련된 행위를 끝낸 후, 물건을 이번엔 이만원짜리를 판다다고 해도 그냥 클래스 사용하면 된다.
  • 하지만 만원에 대한 공급가액을 출력하고 다음은 만원에 대한 부가가치세를 출력하고, 그리고 이만원에 대한 공급가액을 출력하는 것과 같이 클래스의 상태가 계속 바뀌는 경우 인스턴스화 필요하다. (accounting에 대한 하나의 클래스를 여러 상태가 돌려서 사용하고 있기에 accounting 을 복제한 인스턴스를 만들어서 상태를 주면 독립된 인스턴스를 사용 할 수 있음
class Accounting {
    public static double valueOfSupply;
    public static double vatRate = 0.1; // 고정 값으로, 인스턴스를 만들면 메모리가 사용 되기에, 절약을 위해 클래스 소속이 더 나음
    public double getVAT() {
        return valueOfSupply * vatRate;
    }
    public double getTotal() {
        return valueOfSupply + getVAT();
    }

}

public class Hello {
    public static void main(String[] args) {
       Accounting a1 = new Accounting();
       a1.valueOfSupply = 10000.0;

        Accounting a2 = new Accounting();
        a2.valueOfSupply = 20000.0;

        System.out.println(a1.valueOfSupply);
        System.out.println(a2.valueOfSupply);

        System.out.println(a1.getVAT());
        System.out.println(a2.getVAT());

        System.out.println(a1.getTotal());
        System.out.println(a2.getTotal());

    }

}
  • 인스턴스가 생성 될 때 인스턴스가 내부적으로 꼭 가져야할 값인 valueOfSupply 값을 생성자 레벨에서 강제하고 싶다면 아래와 같이 작성한다.
class Accounting {
    public static double valueOfSupply;
    public static double vatRate = 0.1;
    public Accounting (double valueOfSupply) {
        this.valueOfSupply = valueOfSupply;
    }
    public double getVAT() {
        return valueOfSupply * vatRate;
    }
    public double getTotal() {
        return valueOfSupply + getVAT();
    }

}

public class Hello {
    public static void main(String[] args) {
       Accounting a1 = new Accounting(10000.0);

        Accounting a2 = new Accounting(20000.0);

        System.out.println(a1.valueOfSupply);
        System.out.println(a2.valueOfSupply);

        System.out.println(a1.getVAT());
        System.out.println(a2.getVAT());

        System.out.println(a1.getTotal());
        System.out.println(a2.getTotal());

    }

}

9.출처

0개의 댓글