본문 바로가기
프로그래밍/java

6. java 클래스 잘 만들기

by 수삼이는코딩중 2023. 4. 10.
728x90

Person 클래스에 메소드 추가

public class Person {
    String name; //인스턴스필드
    String address;//인스턴스필드
    boolean isVip;//인스턴스필드
    static int count = 0;//클래스필드
    public void printName() { // 인스턴스 메소드
        System.out.println("내 이름은"+name);
    }
    public static void printCount(){ //클래스 메소드
        System.out.println("count:"+name);
    }
}

 

클래스가 가진 메소드는 필드를 내부적으로 사용할 수 있다. 

파라미터로 받는 것 제외하고도, 사용할 수 있다.

printCount() 메소드에서 인스턴스필드를 사용할 수 있을까?

JVM은 Person 클래스가 가지고 있는 static한 것들은 바로 사용가능하도록 메모리에 올린다. 

그러나 인스턴스필드나 메소드를 사용하고 싶으면 인스턴스를 만들고, 참조하는 변수를 선언해야 사용할 수 있다.

static한 메소드에서는 인스턴스 필드나, 인스턴스 메소드를 사용할 수 없다. 왜냐면 생성되는 시점이 다르기 때문에.

static은 이미 메모리에 올라가있어야 하기 때문! 인스턴스를 만들기 전에!

 

static 블럭은 static 클래스 변수를 초기화할 수 있다.

public class Person {
    String name;
    String address;
    boolean isVip;
    static int count = 0;
    static{
        count = 100;
    }
    public void printName() {
        System.out.println("내 이름은"+name);
    }
    public static void printCount(){
        System.out.println("count:"+count);
    }
}

테스트

public class PersonTest3 {
    public static void main(String[] args){
     Person p1 = new Person();
     p1.name = "hongildong";

     p1.printName();
     Person.printCount();
     Person.count++;

     Person.printCount();


    }
}

결과

내 이름은hongildong
count:100
count:101

 

 

main메소드 보다 먼저실행되는 static블록

public class Hello2 {
    static int i;
    static {
        i = 500;
        System.out.println("static block");
    }

    public static void main(String[] args){
        System.out.println("Hello");
    }
}

//javac Hello2.java
//java Hello2

결과

static block
Hello

-> main 메소드 보다 static블럭이 먼저 실행됨을 알 수 있다. 

이걸 이용해서 어떤 작업을 할 수 있다...ㅎ 꼼수 같은..!

 

java 버전별 메모리 생성(java 8 JVM)

java Heap Native Memory
Eden Survivor Old Metaspace(PermGen) C heap Thread Stack

Heap memory는 JVM이 관리하는 메모리 영역

Native Memory는 운영체제가 관리하는 메모리 영역

클래스정보는 Metaspace에 올라간다. 

 

소스코드, 클래스 파일 자체는 정적이다.

  • 동적인 것들은 실행되면서 생성되는 것들을 말한다.
  • 클래스 정보 자체는 정적이다.
  • 클래스 정보는 메모리에 그 정보를 올려서 사용하는 것

기억할 것

  • new연산자를 사용할 때마다 메모리에 인스턴스가 생성된다(처음에 클래스가 메모리에 올라갔으니 두번째 인스턴스는 그 메모리에 있는 클래스를 참조한다.)
  • 인스턴스는 더이상 참조되는 것이 없을 때, 나중에 가비지 컬렉션 된다
  • static한 필드는 클래스가 로딩될 때 딱 한번 메모리에 올라가고 초기화 된다.
  • 인스턴스 메소드(static이 안붙은 메소드)는 인스턴스를 생성하고 나서 레퍼런스 변수를 이용해서 사용
  • 클래스 메소드는 클래스명.메소드명()으로 사용가능하다
  • 메소드 안에 선언된 변수들은 메소드가 실행될 때 메모리에 생성되었다가 메소드가 종료될 때 사라진다. 

 

추상화

중요한 것은 남기고, 불필요한 것은 제거한다.

 

예를 들어

책상은 누가 바라보느냐에 따라서 중요한 부분이 달라진다.

 

캡슐화

관련된 것을 잘 모아서 가지고 있는 것을 캡슐화라고 한다

관련된 것을 잘 모아서 가지고 있을 수록 응집도가 높다고 표현한다. 

클래스 이름이 중요하다. 거기에 필요한 메소드가 모여있을테니.

 

자바는 클래스 지향이 아니라 객체 지향프로그래밍

좋은 객체는 응집도는 높고 결합도는 낮다. 

(결합도가 높다 : 부가적인 장비가 있어야 작동한다.)

 

다형성(polymorphism)

System.out.println(...)

  • println : "인자를 출력하고 줄바꿈을 한다."
  • System이라는 클래스
  • out : System의 필드, printstream
  • println : printstream에 속한 메소드, 무엇을 출력하든 메소드 이름이 같다
  • 여기서 인자는 int, float, double String 등이 있다. 
  • 중요한건 인자에 어떤 타입이 들어가든 메소드 이름이 같다는것. : Overloading

메소드 오버로딩

  • 메소드의 이름은 같고 매개변수의 갯수나 타입이 다른 메소드를 정의 하는 것
  • 리턴값만 다르게 갖는 오버로딩은 작성할 수 없다
  • 메소드를 여러개 제공해주면 사용하는 사람은 편하다. 
  • 서비스 정신이 필요하다. 
public class StandardOutput {
    public void println(boolean b){
        System.out.println(b);
    }

    public void println(int i){
        System.out.println(i);
    }

    public void println(double d){
        System.out.println(d);
    }

    public void println(String s){
        System.out.println(s);
    }

    public static void main(String[] args){
        StandardOutput output = new StandardOutput();
        output.println(100);
        output.println("hello");
        output.println(10.5);
        output.println(false);

    }
}

결과

100
hello
10.5
false

댓글