상속에서의 생성자 호출 순서
자식 클래스의 생성자에서 명시적으로 부모 클래스의 생성자가 호출되지 않으면 자동으로 부모 클래스의 default 생성자가 호출된다.
부모 클래스에 디폴트 생성자가 없는 경우도 있는데 그럴 때는 부모 클래스의 다른 생성자를 반드시 호출해야 한다.
자식 클래스의 생성자에서 명시적으로 부모 클래스의 생성자를 호출할 수도 있다.
super 키워드를 사용하여 부모 클래스의 생성자를 호출할 수 있는데, 이때 super 키워드는 자식 생성자의 첫째 줄에 호출되어야 한다. 그러지 않으면 'Constructor call must be the first statement in a constructor'라는 오류 문구가 뜬다.
예제
현재 코드에서 상속은 (부모) Vehicle - Car - HybridCar (자식) 순서이다.
Main.java
public class Main {
public static void main(String[] args) {
// Vehicle 클래스의 인스턴스 생성
Vehicle v1 = new Vehicle();
Vehicle v2 = new Vehicle(100);
System.out.println();
// Car 클래스의 인스턴스 생성
Car car1 = new Car();
System.out.println();
// HybridCar 클래스의 인스턴스 생성
HybridCar car2 = new HybridCar();
System.out.println();
Car car3 = new Car(100, 60);
System.out.println();
HybridCar car4 = new HybridCar(120, 800);
}
}
Vehicle.java
public class Vehicle {
int speed;
public Vehicle() {
System.out.println("Vehicle()생성");
}
public Vehicle(int speed) {
super();
this.speed = speed;
System.out.println("Vehicle(int) 생성 : speed = " + speed);
}
}
Car.java
public class Car extends Vehicle {
int oil;
public Car() {
super(45);
System.out.println("Car() 생성");
}
public Car(int oil) {
this.oil = oil;
System.out.println("Car(int) 생성 : oil = " + oil);
}
public Car(int oil, int speed) {
this.oil = oil;
System.out.println("Car(int) 생성 : oil = " + oil + ", speed = " + speed);
}
}
Car의 기본 생성자에서 super(45);를 작성해줌으로써 상속받은 Vehicle의 매개변수가 1개인 생성자를 호출하게 된다.
부모 클래스의 인스턴스가 생성되고 나서 자식 클래스의 인스턴스가 생성되는 것이다.
따라서 Vehicle(int) 생성 : speed = 45라는 문구가 먼저 출력된 뒤, Car() 생성이라는 문구가 출력될 것이다.
HybirdCar.java
public class HybridCar extends Car {
int electricity;
public HybridCar() {
System.out.println("HybridCar() 생성");
}
public HybridCar(int electricity) {
System.out.println("HybridCar(int) 생성 : electricity = " + electricity);
this.electricity = electricity;
}
public HybridCar(int electricity, int oil) {
this(electricity);
System.out.println("HybridCar(int, int) 생성 : oil = " + oil);
this.oil = oil;
}
}
HybridCar 클래스의 기본 생성자에서는 부모 클래스의 생성자가 호출되지 않았기 때문에 자동으로 부모 클래스의 기본 생성자가 호출된다.
매개변수가 2개 있는 HybridCar 생성자에서는 this(electricity); 를 썼는데 이는 생성자를 위임(Contructor delegation)하는 것으로, 매개변수 한 개를 필요로 하는 생성자가 호출되는 것이다.
따라서 public HybridCar(int electricity, int oil) 생성자를 사용해 객체를 생성하는 경우 public HybridCar(int electricity) 생성자도 호출된다.
실행 결과
관련 글