외부 클래스 | 하위 클래스 | 동일 패키지 | 내부 클래스 | |
---|---|---|---|---|
public | O | O | O | O |
protected | X | O | O | O |
선언되지 않음 (default) | X | X | O | O |
private | X | X | X | O |
- 하위 클래스가 생성될 때 상위 클래스가 먼저 생성된다.
- 상위 클래스의 생성자가 호출되고 하위 클래스의 생성자가 호출된다.
Customer 클래스의 기본 생성자와 VIPCustomer 클래스의 기본 생성자에 출력문을 추가하여 확인해보자.
public class Customer {
Customer(){
System.out.println("Customer() 호출");
}
}
public class VIPCustomer extends Customer{
public VIPCustomer() {
System.out.println("VIPCustomer() 호출");
}
}
public class CustomerTest {
public static void main(String[] args) {
VIPCustomer customerKim = new VIPCustomer();
}
}
main 함수가 있는 CustomerTest 클래스에서 VIPCustomer 객체를 생성하여 출력해보면 상위 클래스인 Customer 클래스의 생성자가 먼저 호출된 것을 확인할 수 있다.
- 하위 클래스의 생성자에서는 무조건 상위 클래스의 생성자가 호출되어야 함
- 아무것도 없는 경우 컴파일러는 상위 클래스 기본 생성자를 호출하기 위한 super() 를 코드에 넣어 줌
즉, 위 코드에서 VIPCustomer 클래스의 생성자에는 super() 를 자동으로 호출해준 것이다.
Customer 클래스의 생성자도 super() 가 자동으로 호출되는데, java의 최상위 클래스인 Object 클래스의 생성자가 호출된 것이다.
public class VIPCustomer extends Customer{
public VIPCustomer() {
super(); //이걸 안써도 컴파일러가 자동으로 넣어 줌
System.out.println("VIPCustomer() 호출");
}
}
- 만약 상위 클래스의 기본 생성자가 없는 경우 (매개변수가 있는 생성자만 존재하는 경우) 하위 클래스는 명시적으로 상위 클래스를 호출해야 한다.
Customer 클래스의 기본 생성자를 없애고, 매개변수를 받는 constructor를 만들어준다면 VIPCustomer 클래스의 생성자에서는 Super(매개변수)를 통해 생성자를 호출해주어야 한다.
public class Customer {
Customer(int customerID, String customerName){
this.customerID = customerID;
this.customerName = customerName;
System.out.println("Customer(int, String) 호출");
}
}
// [리마인드] 하나라도 constructor를 만들면 컴파일러는 default constructor를 만들어 주지 않는다.
public class VIPCustomer extends Customer{
public VIPCustomer() {
super(1001, "이순신"); // 이렇게 Super(매개변수)를 통해 생성자를 호출
System.out.println("VIPCustomer() 호출");
}
public VIPCustomer(int customerID, String customerName) {
super(customerID, customerName);
System.out.println("VIPCustomer(int, String) 호출");
}
}
Customer vc = new VIPCustomer(); 에서 vc가 가리키는 것은?
VIPCustomer() 생성자의 호출로 인스턴스는 모두 생성 되었지만
타입이 Customer이므로 접근 할 수 있는 변수나 메서드는 Customer의 변수와 메서드 임.