Super class와 Sub class의 생성자 호출 및 실행 관계

여러가지 예시 코드와 질문과 답으로 상속과 생성자를 알아보자.

 

먼저, 이세상 모~~~든 객체들은 생성되기 위해서 반드시 생성자를 호출해야한다.

 

그럼 여기서 질문!

 

Q) 서브 클래스의 객체가 생성될 때 생성자는 몇 번 호출될까?(super와 sub class 두개의 class만 있다고 가정)

A) 정답은 두번이다.

자 생각해보자. 자식이 있기위해서는 부모부터 있어야 할것이다.

그렇다면? 자식을 생성하기 위해서는 부모부터 먼저 생성을 해야한다. 

따라서 슈퍼 클래스의 생성자를 호출한 후 서브 클래스의 생성자가 실행된다.

 

서브 클래스의 생성자가 먼저 호출되고 난 후 슈퍼 클래스의 생성자가 호출되는것은 이제 알겠는데....

서브 클래스의 여러 생성자 중 하나가 실행되고, 슈퍼 클래스의 여러 생성자 중 하나가 실행될텐데....

 

여기서 질문!

 

Q) 서브 클래스의 생성자 중 어떤 것과 슈퍼 클래스의 생성자 중 어떤 것이 서로 짝을 이룰까?

A) 4가지 경우로 나눠서 생각해 보자.

 

1. 서브 클래스 기본 생성자 <---> 슈퍼 클래스 기본 생성자

아래와 같은 경우 A(슈퍼클래스)와 B(서브 클래스)모두 기본 생성자 이므로 자동으로 기본 생성자 끼리 짝을 맺는다.

class A{
	public A(){
		System.out.println("생성자A");
	}
	public A(int x){
		
	}
}

class B extends A{
	public B(){
		System.out.println("생성자B");
	}
}
<<<결과값>>>
생성자A
생성자B

 

2. 서브 클래스 기본 생성자 <---> 슈퍼 클래스 명시적 생성자

그럼 다음과 같이 A(슈퍼 클래스)에 기본 생성자가 없는 경우는 public B()에 대한 짝을 찾을 수가 없어 에러가 발생한다.

class A{
	public A(int x){
		System.out.println("생성자A");
	}
}

class B extends A{
	public B(){
		System.out.println("생성자B");
	}
}
<<<결과값>>>
Implicit super constructor A() is undefined.......(에러)

 

3. 서브 클래스 명시적 생성자 <---> 슈퍼 클래스 기본 생성자

아래와 같이 B(서브 클래스)클래스의 명시적 생성자를 호출했을 경우 슈퍼 클래스 생성자에 대한 특별한 지시가 없으면 기본 생성자가 호출된다.

class A{
	public A(){
		System.out.println("생성자A");
	}
	public A(int x){
		System.out.println("매개변수 생성자A");
	}
}

class B extends A{
	public B(){
		System.out.println("생성자B");
	}
	public B(int x){
		System.out.println("매개변수 생성자B");
	}
}
public class Test{
	public static void main(String[] args){
		B b = new B(5);
	}
}
<<<결과값>>>
생성자A
매개변수 생성자B

 

4. 서브 클래스 명시적 생성자 <---> 슈퍼 클래스 명시적 생성자

B 클래스(서브 클래스)의 생성자에서 super(x)로 슈퍼 클래스 생성자의 호출을 명시적으로 하면 슈퍼 클래스의 명시적 생성자가 호출된다.

class A{
	public A(){
		System.out.println("생성자A");
	}
	public A(int x){
		System.out.println("매개변수 생성자A");
	}
}

class B extends A{
	public B(){
		System.out.println("생성자B");
	}
	public B(int x){
		super(x);
		System.out.println("매개변수 생성자B");
	}
}
public class Test{
	public static void main(String[] args){
		B b = new B(5);
	}
}
<<<결과값>>>
매개변수 생성자A
매개변수 생성자B

 

 

이해가 안간다면 마지막으로 내 코드를 보면서 한번더 복습해 보자!!

Product(슈퍼클래스) - TV, Refrigerator(서브클래스)

// 명시적 생성자만 만들어 주었으므로 기본 생성자를 호출 못함
class Product {
	private int serialNo;
	private String productName;
	private int price;
	private int stock;
	public Product(int serialNo, String productName, int price, int stock) {
		this.serialNo = serialNo;
		this.productName = productName;
		price = price;
		this.stock = stock;
	}
	
	public String getProduct() {
		return serialNo+"\t"+productName+"\t"+price+"\t"+stock+"\t";
	}
}

//super(...)로 명시적으로 슈퍼 클래스의 명시적 생성자 호출
class Refrigerator extends Product{
	private double volume;

	public Refrigerator(int serialNo, String productName, int price, int stock, double volume) {
		super(serialNo, productName, price, stock);
		this.volume = volume;
	}
	
	@Override
	public String toString() {
		return super.getProduct() + volume;	//이부분은 추후 설명
	}
}

class TV extends Product{
	private double inchi;
	private String displayType;
	
    //super(...)로 명시적으로 슈퍼 클래스의 명시적 생성자 호출
	public TV(int serialNo, String productName, int price, int stock, double inchi, String displayType) {
		super(serialNo, productName, price, stock);
		this.inchi = inchi;
		this.displayType = displayType;
	}
	
	@Override
	public String toString() {
		return super.getProduct() + inchi + "\t" + displayType;
	}
}

public class ProductTest {
	public static void main(String[] args) {
    	//명시적으로 서브 클래스의 생성자 호출
		TV tv = new TV(11111, "aaa", 1500000, 125, 62.0, "eee");
		Refrigerator refrigerator = new Refrigerator(22222, "bbb", 3650000, 263, 825.0);
		
        //추후 객체와 toString 관계에 대해 설명할 계획
		System.out.println(tv);	
		System.out.println(refrigerator);
	}

}

 

다음으로는 메소드 오버라이딩에 대해 알아봅시당~~!!

Posted by Jyoel :