Java

[인프런] super

sejin2 2024. 5. 27. 14:41

super - 부모 참조

부모와 자식의 필드명이 같거나 메서드가 오버라이딩 되어 있으면, 자식에서 부모의 필드나 메서드를 호출할 수 없다. 이때 super 키워드를 사용하면 부모를 참조할 수 있다. super는 이름 그대로 부모 클래스에 대한 참조를 나타낸다.

public class Parent {
    public String value = "parent";

    public void hello() {
        System.out.println("Parent.hello");
    }
}
public class Child extends Parent {

    public String value = "child";

    @Override
    public void hello() {
        System.out.println("child.hello");
    }

    public void call() {
        System.out.println("this value = " + this.value); // this 생략 가능
        System.out.println("super value = " + super.value);

        this.hello();
        super.hello();
    }
}
public class Super1Main {
    public static void main(String[] args) {
        Child child = new Child();
        child.call();
    }
}

call( ) 메서드를 보면, this는 자기 자신의 참조를 뜻하며 생략이 가능하다. 
super는 부모 클래스에 대한 참조를 뜻한다. 
필드 이름과 메서드 이름이 같지만 super를 사용해 부모클래스의 기능을 사용할 수 있다. 

super메모리 그림

본인한테 있지만 부모의 기능을 호출하고 싶을 때 super를 사용하면 부모에게서 찾을 수 있게 된다. 

super - 생성자

상속 관계의 인스턴스를 생성하면 결국 메모리 내부에는 자식과 부모 클래스가 각각 만들어진다. 
따라서 각각의 생성자도 모두 호출되어야 한다.

상속 관계를 사용하면 자식 클래스의 생성자에서 부모 클래스의 생성자를 반드시 호출해야 한다. ( 규칙 )
상속 관계에서 부모의 생성자를 호출할 때에는 super를 사용하면 된다.
public class ClassA {

    public ClassA() {
        System.out.println("ClassA 생성자");
    }
}

ClassA 는 최상위 부모 클래스이며, 매개변수가 없는 기본 생성자를 가지고 있다. 

public class ClassB extends ClassA{

    public ClassB(int a) {
        super(); // 기본 생성자 생략 가능
        System.out.println("ClassB 생성자 a = " + a);
    }

    public ClassB(int a, int b) {
        super();
        System.out.println("ClassB 생성자 a=" + a + "b = " + b);
    }
}

ClassB는 ClassA를 상속받았다. 
상속을 받으면 생성자의 첫줄에 super를 사용해서 부모 클래스의 생성자를 호출해야 한다. 
예외로 생성자 첫줄에 this를 사용할 수는 있지만, super는 자식의 생성자 안에서 언젠가는 반드시 호출해야 한다. 

부모 클래스의 생성자가 기본 생성자인 경우에는 super(  )를 생략할 수 있다. 
상속 관계에서 첫 줄에 super를 생략하면 부모의 기본 생성자를 호출하는 super( ) 를 자동으로 만들어 준다. 

public class ClassC extends ClassB{

    public ClassC() {
        super(10, 20);
        System.out.println("ClassC 생성자");
    }
}

ClassC는 ClassB를 상속 받았으며, ClassB에는 두 생성자가 있다. 
생성자는 하나만 호출할 수 있으며, 두 생성자 중에서 하나를 선택하면 된다. 
ClassB에는 기본생성자가 없기 때문에 super를 직접 정의해주어야 한다. 기본 생성자를 호출하는 super(  )는 사용하거나 생략할 수 없다.  

public class Super2Main {
    public static void main(String[] args) {
        ClassC classC = new ClassC();
    }
}

생성자의 실행 순서가 결과적으로 최상위 부모로부터 실행되어 하나씩 아래로 내려온다. 따라서 초기화는 최상위 부모부터 이루어진다. 자식 생성자의 첫줄에서 부모 생성자를 호출해야 하기 때문이다. 

 

 

공부 내용: [인프런] 김영한의 실전 자바 - 기본편

'Java' 카테고리의 다른 글

instanceof  (0) 2024.05.27
[인프런] 다형성  (0) 2024.05.27
[인프런] 상속과 접근 제어  (0) 2024.05.27
[인프런] 상속과 메서드 오버라이딩  (0) 2024.05.27
[인프런] 상속  (0) 2024.05.27