상속과 다형성 - 5. super와 super( )

Ⅴ. super와 super( )

1. super 키워드 vs super() 메소드

 - super 키워드부모클래스의 객체

    - 필드명 중복 또는 메소드 오버라이딩으로 가려진 부모의 필드/메소드를 호출하기 위해 주로 사용

// Example1 
// 멤버 앞에 참조변수를 생략(this.)하는 경우의 메소드 호출
package sample

class A {
	void abc() {
		System.out.println("A 클래스의 abc()");
	}
}

class B extends A {	
	void abc() {
		System.out.println("B 클래스의 abc()");
	}
	void bcd() {
		abc(); // this.abc(); 와 동일 (this는 나 자신, super는 부모)
	}
}

public class Main {	
	public static void main(String[] args) {
		// 1. 객체 생성
		B bb = new B();
		
		// 2. 메소드 호출
		bb.bcd();	// B 클래스의 abc()
	}
}

 

// Example2
// 멤버앞에 super 키워드를 사용한 경우의 메소드 호출
package sample;

class A {
	void abc() {
		System.out.println("A 클래스의 abc()");
	}
}

class B extends A {	
	void abc() {
		System.out.println("B 클래스의 abc()");
	}
	void bcd() {
		super.abc(); 	// super.abc() : 부모클래스 객체의 abc() 메소드 호출;
	}
}

public class Main {
	public static void main(String[] args) {
		// 1. 객체 생성
		B bb = new B();
		
		// 2. 메소드 호출
		bb.bcd(); 	// A 클래스의 abc()
	}
}

 

 - super( ) 메소드  부모 클래스의 생성자를 호출 (생략시, 컴파일러가 자동으로 삽입)

    → 자식 클래스 객체 속에 부모 객체가 포함될 수 있었던 이유임

    ※ 모든 클래스 안에는 생성자가 존재

    - super() 메소드는 생성자 내부에서만 사용가능

    - 반드시 중괄호 이후 첫 줄에 위치하여야 함

    - 자식클래스 생성자의 첫 줄에는 반드시 this() 또는 super()가 포함되어야 함

        → (생략시, 컴파일러가 자동으로 super( ) 추가)

// Example1
// super() 메소드의 기능 및 컴파일러에 의한 자동추가 super()
package sample;

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

class B extends A {
	B() {
		super();	// 생략시, 컴파일러가 자동 추가 (부모클래스의 생성자 호출), (자식만 가능)
		System.out.println("B 생성자");
	}
}

class C {
	C(int a) {
		System.out.println("C 생성자");
	}
}

class D extends C {
	/* 컴파일러가 자동으로 추가해주는 내용
	D(){         
		super();	// C는 인자가 요구되므로(ina a) 자동생성이 불가능함
	}            
	*/
	D() {
		super(3);	// 3은 int a 에 넣는 값
	}
}

public class Main {
	public static void main(String[] args) {
		// 1. A 객체 생성
		A aa = new A();		// A 생성자
	
		// 2. B 객체 생성
		B bb = new B();		// A 생성자 -> B 생성자
	}
}

 

// Example2
// this()메소드와 super() 메소드의 혼용
package sample;

class A {
	A() {
		this(3);
		System.out.println("A 생성자 1");
	}
	A(int a){
		System.out.println("A 생성자 2");
	}
}

class B extends A {	
	B() {
		this(3);
		System.out.println("B 생성자 1");
	}
	B(int a) {
		System.out.println("B 생성자 2");
	}
}

public class Main {
	public static void main(String[] args) {
		// 1. A 객체 생성
		A aa1 = new A();	// A 생성자 2 A 생성자 1
		System.out.println();
		A aa2 = new A(3);	// A 생성자 2
		System.out.println();
		
		// 2. B 객체 생성
		B bb1 = new B();	// A 생성자 2 A 생성자 1 B 생성자 2 B 생성자 1
		System.out.println();
		B bb2 = new B(3);	// A 생성자 2 A 생성자 1 B 생성자 2
	}
}

 

// Example3
package sample;

class Car {
	String color;
	Car(){}
	Car(String color) {
		this.color = color;
	}
	void drive() {
		System.out.println("부릉 부릉");
	}
}

class Avante extends Car {
	Avante() {
		super("white");
	}
	Avante(String color) {
		super(color);
	}
	void drive() {
		super.drive();		// 부모의 drive() 메소드 출력
		System.out.println("부와아아앙");
	}
	void accel() {
		this.drive();		// 내 자신의 drive() 메소드 출력
	}
}

public class Main {
	public static void main(String[] args) {
		Avante myCar = new Avante("gray");
		myCar.drive();		// 부릉 부릉 부와아아앙
		myCar.accel();		// 부릉 부릉 부와아아앙
	}
}