자바/객체지향 프로그래밍(OOP)

super() 정리1

Blue_bull 2025. 1. 21. 16:26

자바에서 모든 클래스는 Object를 암시적으로 상속받기 때문에, 상속을 명시적으로 받지 않아도 모든 클래스의 생성자에는 기본적으로 super()가 포함됩니다. 또한, 상속 관계에서는 super가 호출하는 생성자가 매개변수에 맞는 생성자를 상위 클래스에서 계속 찾아가며, 최상위 클래스(Object)까지 올라갑니다.

상속과 super의 동작 원리 요약

  1. Object는 모든 클래스의 최상위 부모:
    • 클래스가 명시적으로 extends로 다른 클래스를 상속받지 않더라도, 기본적으로 Object 클래스를 상속받습니다.
    • 따라서 모든 클래스에는 super()가 암시적으로 포함됩니다.
  2. super() 호출의 기본 규칙:
    • 자식 클래스의 생성자가 호출되면, 해당 생성자에서 먼저 부모 클래스의 생성자를 호출합니다.
    • 호출할 때, super()에 전달된 매개변수와 일치하는 생성자를 부모 클래스에서 찾습니다.
    • 부모 클래스에 해당 매개변수의 생성자가 없다면, 상위 클래스로 계속 올라가면서 매개변수에 맞는 생성자를 찾습니다.
  3. 최상위 클래스까지 올라감:
    • 이 과정은 최상위 클래스인 Object의 생성자까지 올라가며, 최종적으로 Object 클래스의 기본 생성자가 호출됩니다.
    • Object 클래스는 기본 생성자만 가지므로, 더 이상 올라갈 필요가 없습니다.

예제 코드: 상속 관계에서의 super() 동작

class GrandParent {
    public GrandParent() {
        System.out.println("GrandParent Default Constructor");
    }

    public GrandParent(String msg) {
        System.out.println("GrandParent Constructor: " + msg);
    }
}

class Parent extends GrandParent {
    public Parent() {
        super("Hello from Parent"); // 2. GrandParent의 매개변수 생성자 호출
        System.out.println("Parent Default Constructor"); // 3. Parent의 기본 생성자 출력
    }
}

class Child extends Parent {
    public Child() {
        super(); // 1. Parent의 기본 생성자 호출
        System.out.println("Child Default Constructor"); // 4. Child의 기본 생성자 출력
    }
}

public class Main {
    public static void main(String[] args) {
        Child child = new Child(); // Main 시작
        /*
         * 실행 순서:
         * 1. Parent의 기본 생성자 호출
         * 2. GrandParent의 매개변수 생성자 호출
         *    출력: "GrandParent Constructor: Hello from Parent"
         * 3. Parent 기본 생성자의 내용 실행
         *    출력: "Parent Default Constructor"
         * 4. Child 기본 생성자의 내용 실행
         *    출력: "Child Default Constructor"
         */
    }
}

출력 결과:

GrandParent Constructor: Hello from Parent
Parent Default Constructor
Child Default Constructor

설명:

  1. Child 클래스의 생성자가 호출되면, super()로 인해 Parent 클래스의 기본 생성자가 호출됩니다.
  2. Parent 클래스의 생성자는 super("Hello from Parent")를 호출하며, GrandParent 클래스의 매개변수 생성자를 호출합니다.
  3. GrandParent 클래스의 매개변수 생성자가 실행됩니다.
  4. 호출 순서는 항상 자식 → 부모 → 조부모 → 최상위 클래스(Object)로 올라갑니다.

super의 매개변수 처리 규칙

  • 매개변수와 동일한 생성자를 찾기:
    • super() 또는 super(매개변수)는 부모 클래스에서 해당 매개변수와 일치하는 생성자를 먼저 찾습니다.
    • 찾지 못하면 컴파일 오류가 발생합니다.
    • 부모 클래스에서 기본 생성자(public Parent())를 제공하지 않고, 매개변수가 있는 생성자만 있다면, 반드시 명시적으로 적절한 super(매개변수)를 호출해야 합니다.

매개변수가 없는 부모 생성자가 없을 때의 예제:

class Parent {
    public Parent(String msg) {
        System.out.println("Parent Constructor: " + msg);
    }
}

class Child extends Parent {
    public Child() {
        super(); // 오류 발생: 매개변수 없는 생성자가 Parent에 없음
    }
}

오류 메시지:

constructor Parent in class Parent cannot be applied to given types;
  required: String
  found: no arguments

해결:

public Child() {
    super("Hello"); // 부모 클래스의 매개변수 생성자 호출
}

결론

  1. 모든 클래스는 Object를 상속받기 때문에, 생성자에는 기본적으로 super()가 암시적으로 포함됩니다.
  2. 상속 관계에서는 super()가 부모 클래스의 생성자를 호출하며, 매개변수에 맞는 생성자를 상위 클래스에서 계속 찾아 올라갑니다.
  3. 최상위 클래스는 항상 Object이며, Object의 기본 생성자로 호출 흐름이 종료됩니다.
  4. 만약 적절한 생성자를 찾지 못하면 컴파일 오류가 발생하며, 명시적으로 super(매개변수)를 작성해 해결해야 합니다.