tuter77

Java : 상속(2) 및 복습. 본문

JavaStudy

Java : 상속(2) 및 복습.

tuter77 2023. 1. 29. 20:08

● 상속에서 클래스 생성과정과 형 변환

▷하위 클래스가 생성되는 과정

- 하위 클래스를 생성하면 상위클래스가 먼저 생성된다.

- new VIPCustomer()를 호출하면 Custormer() 가 먼저 생성된다.

-예제를 통해 보면,

	public Customer() {
		
		customerGrage = "SILVER";
		bonusRatio = 0.01;
		
		System.out.println("Customer() call");
		
	}
	public VIPCustomer() {
		
		bonusRatio = 0.05;
		salesRatio = 0.1;
		customerGrage = "VIP";
		
		System.out.println("VIPCustomer() call");
	}

이와 같이 코드를 작성했을때 Test클래스에서 vip만 호출해보면 customer 클래스가 먼저 호출되고 나서 vip 클래스가 호출되는 것을 볼 수 있다.

이는 생성자가 없는 경우 자바에서 super() 라는 생성자를 통해 상위 클래스를 자동으로 호출해주기 때문이다.

 

● java 복습

실시간 강의를 통해 온라인 강의 java 내용을 복습하다 금방 잊은 내용들을 다시 정리했다.

 

▷this

- 생성자를 통해 this 키워드를 전달할 수 있는데, 여러 클래스 간 하나의 객체를 전달해서 사용해야 하는 경우에도 유용하다. 

- this 키워드를 사용해 현재 클래스의 메서드를 호출할 수 있는데, 따로 사용하지 않으면 컴파일러가 this 키워드를 자동으로 추가한다.

- 일반적으로 getter/setter 메서드에서 내부값을 할당하거나 접근할 때 사용한다.

-this는 각 인스턴스 메서드의 Stack Frame에 this라는 로컬변수로 메모리영역에 존재한다.

 

▷ static

- static 키워드는 주로 메모리 관리에 사용되는데 변수, 메서드, 블록, inner class에 사용할 수 있다.

- class에 선언된 static member들을 class member라고 하고, 각각 class variable 또는 class method 라고 부른다. 또한 class가 load 되어있는 동안 사용한다.

- class variable, method는 instance들 사이에서 공유하는데, 여러 Thread가 접근할 경우 동기화 문제가 발생하며, 이럴 경우 synchronize와 같은 방법을 사용해 한번에 하나의 thread만 사용할 수 있게 지정한다.

- 이러한 static method는 math class 처럼 산술계산, 날짜 변환등의 공통적으로 사용되는 기능일 경우 적용한다. 또한 static 객체 역시 회사, 지명 등 하나만 존재해야하는 변수의 경우에 적용한다.

- 메모리는 Heap영역이 아닌 Class Area에 존재하므로 instace를 통한 접근을 하지 않는다. (java 8버전 부터 Heap영역으로 이동했다.)

- 클래스명.멤버(변수 또는 메소드)로 접근한다.

 

▷ 정적 변수

 - 앞서 살펴본 static variable, constant 는 java 8 버전 이전에는PermGen 메모리영여겡 저장되었으나, 8버전 이후로는 Heap 영역으로 옮겨져 GC의 대상이 되도록 변경되었다.- 이유는 기본 용량이 64 MB의 PermGen에 대량 데이터 저장응로 OutOfMemory error가 종종 발생했기 때문이다.

 

위와 같이 8버전 이후로는 OS가 용량을 관리해주는 형태로 바뀌었지만, 과도한 데이터로 OutOfMemory 에러가 날 수 있음은 매한가지이기에, 관리를 잘 해주어야한다.

▷static initializers

- 클래스에서 선언된 static initializers는 클래스가 초기화 될 때 실행되며, 클래스 변수에 대한 초기화에 사용된다.

실행 순서가 중요한데 class load > static initializer 실행 > 생성자 호출 순이다.

public class StaticInitializer {
    static int age = 10;
    static{
        System.out.println("#1 static initializer 진입");
        System.out.println("#2 static age 변수 접근 = " + age);
        // afterVar 변수가 미리 선언되어 있지않아 compile Error 발생
//        System.out.println("static afterVar is " + afterVar);
    }

    static int afterVar = 20;

    StaticInitializer(){
        System.out.println("#6 생성자 호출"); //6
    }

    static {
//        System.out.println("static afterVar is " + afterVar);
        System.out.println("#3 두번째 static initializer 진입");
    }

    public static void main(String[] args){
        System.out.println("#5 메인 메서드 시작");
        StaticInitializer s = new StaticInitializer();
        System.out.println("#7 생성자 호출 후 초기화된 Non-static 변수 접근 : " + s.nonStaticVar);
    }

    static {
        System.out.println("#4 세번째 static initializer 진입");
    }

    int nonStaticVar; //인스턴스 변수

}

위는 실행순서를 알아보기 위한 코드로 main()을 실행해보면, static 블록의 위치에 상관없이 class load > static initializer 실행 > 생성자 호출로 실행됨을 알 수 있다.

결과)

▷ static - Singleton Design Pattern 

- 면접질문으로 다수 등장한다는 싱글톤 패턴은 앞서 살펴본바와 같이, 하나의 객체만 존재해야하는 경우 사용하는 디자인 패턴이다.

- 예시로 보면 아래와 같다.

final class Singleton {
    private  static Singleton s =new Singleton();
    private Singleton(){}

    public static Singleton getInstance(){
        if(s == null){
            s = new Singleton();
        }
        return s;
    }
}
public class SingletonTest {
    public static void main(String args[]){
        //Singleton s = new Singleton();
        Singleton s = Singleton.getInstance();
    }
}

접근제어를 private로 선언해 해당 인스턴스를 함부로 생성할 수 없게 막아놓고, getInstance 메서드를 통해 인스턴스를 사용하게 한다. 

아래 test 클래스에서 볼 수 있듯, static으로 선언 되었기 때문에 new로 접근하는 것이 아닌,  getInstance 메서드를 통해 접근한다.

 

위 내용은 2023.01.02에 공부한내용입니다.

링크 : https://dudwls3278.tistory.com/32