상속 관계에서 하위 클래스가 생성 될 때 상위 클래스가 먼저 생성 됩니다. 이는 하위 클래스에서 상위 클래스의 변수나 메서드를 사용기 위해서는 상위클래스를 생성할 필요하기 때문입니다.
생성되는 순서는 상위 클래스의 생성자가 호출되고 하위 클래스의 생성자가 호출됩니다. 위에서 얘기했듯이 하위 클래스의 생성자에게는 무조건 상위 클래스의 생성자가 호출되어야 합니다.
아래의 예와 같이 각각의 클래스의 생성자에 클래스가 생성될 때 마다 호출문을 출력하게 해서 Vip 클래스를 생성하면 가장아래의 테스트 결과 처럼 상위클래스인 Customer 클래스가 먼저 생성되고 VIPCustomer클래스가 생성되는 것을 확인할 수 있습니다.
//Customer 클래스
public Customer() {
customerGrade = "silver";
bonusRatio = 0.01;
System.out.println("Customer() 생성자 호출");
}
//VIPcustomer 클래스
public VIPCustomer () {
salesRatio = 0.1;
bonusRatio = 0.05;
customerGrade = "VIP";
System.out.println("VIPCustomer() 생성자 호출");
}
//테스트 클래스
VIPCustomer Kim = new VIPCustomer();
Kim.setCustomerId(10020);
Kim.setCustomerName("김유신");
Kim.bonusPoint = 10000;
System.out.println(Kim.showCustomerInfo());
//Customer() 생성자 호출
//VIPCustomer() 생성자 호출
//김유신님의 등급은 VIP이며, 적립된 보너스 포인트는 10000점 입니다
하위 클래스에서 상위 클래스의 생성자를 호출하는 코드가 없는 경우 컴팡이러는 상위클래스 기본 생성자를 호출하기 위한 super()를 추가합니다. super()는 생성자를 호출하는 this()와 비슷한 역할을 하는데 자기자신의 생성자를 호출하는 역할을 합니다.
위의 코드에서 상위 클래스를 호출하지 않았는데도 자동으로 호출이 된것은 컴파일을 할 때 Super()라는 문구가 Customer 클래스에 자동으로 생성되었기 때문입니다.
super()로 호출되는 생성자는 상위클래스의 기본생성자입니다. 만약 상위 클래스의 기본생성자가 없는 경우(매개변수가 있는 생성자만 존재 하는 경우) 하위 클래스는 명시적으로 상위 클래스의 생성자를 호출해야 합니다.
다시 한번 위의 Customer클래스의 생성자를 살펴보면 매개변수가 없는 기본생성자임을 확인할 수 있고 그렇기 때문에 super()가 호출이 되었던 것 입니다.
//Customer 클래스
public Customer(int customerId, String custoemrName) {
this.customerId=customerId;
this.customerName=custoemrName;
customerGrade = "silver";
bonusRatio = 0.01;
System.out.println("Customer() 생성자 호출");
}
//VIPCustoemr 클래스
public VIPCustomer(int customerId, String custoemrName) {
super(customerId, custoemrName);
salesRatio = 0.1;
bonusRatio = 0.05;
customerGrade = "VIP";
System.out.println("VIPCustomer() 생성자 호출");
}
//테스트 클래스
VIPCustomer Kim = new VIPCustomer(10020,"김유신");
//Kim.setCustomerId(10020);
//Kim.setCustomerName("김유신");
Kim.bonusPoint = 10000;
System.out.println(Kim.showCustomerInfo());
//Customer() 생성자 호출
//VIPCustomer() 생성자 호출
//김유신님의 등급은 VIP이며, 적립된 보너스 포인트는 10000점 입니다
위의 코드의 Customer 클래스의 생성자처럼 기본생성자가 아닌 매개변수가 존재하는 생성자만 Customer클래스의 있을 때는 아래의 VIPCustomer클래스의 생성자처럼 super()를 통해 Customer 생성자를 수동으로 생성해주어야 하위 클래스를 사용할 수 있습니다.
다시 테스크 클래스로 돌아가 customerId와 customerName을 입력하면 이전과 같은 결과를 얻을 수 있습니다.
아래의 그림처럼 메모리 상으로도 하위 클래스를 생성했을 때 상위클래스의 인스턴스가 먼저 생성되고 하위클래스 인스턴스가 생성이 됩니다.
하위 클래스는 상위 클래스의 타입을 내포하고 있음으로 위의 그림과 같이 상위 클래스 형으로 변수를 선언하고 하위 클래스 인스턴스를 생성 할 수 있습니다.
이는 상위클래스의 묵시적 형변환(특별한 처리없이 형변환이 되는 것)이 일어나는 것으로 상속관계에서 모든 하위 클래스는 상위클래스로 묵시적 형 변환이 가능합니다.
이때 참조변수 vc가 가리킬 수 있는 범위는 Customer클래스의 멤버 변수와 메서드로 제한됩니다. 이는 VIPCustomer의 인스턴스가 선언되어 확장된 멤버 변수와 메서드는 메모리에 잡혀있지만 Customer를 자료형으로 하기 때문에 vc에서 실제 사용할 수 있는 범위도 Customer의 변수와 메서드로 제한이 되는 것입니다.
하지만 그 역인 상위 클래스가 하위클래스로 묵시적 형변환이 일어나지는 않습니다.
위의 그림 처럼 계층구조가 여러개여도 하위 클래스는 상위 클래스를 변수로 선언하고 인스턴스를 생성할 수 있습니다. 즉 상속 단계의 상관없이 하위클래스에서 상위클래스로에 묵시적 형변환 일어나는 것을 알 수 있습니다.