[Java] 클래스 설계에서 생성자 호출 구조 이해하기: this()와 super()

Java에서 객체를 생성할 때 가장 먼저 실행되는 것이 바로 생성자(Constructor)입니다. 생성자는 객체의 필드를 초기화하고, 상태를 정의하는 중요한 역할을 해요. 그런데 생성자가 하나 이상이거나, 상속 관계에 있는 클래스에서 객체를 만들게 되면 다른 생성자를 호출하거나 부모 클래스의 생성자를 호출해야 할 상황이 생기게 됩니다.

 

이때 사용하는 것이 바로 this() super() 키워드입니다.

  • this()는 같은 클래스의 다른 생성자를 호출할 때
  • super()는 부모 클래스의 생성자를 호출할 때 사용됩니다.

✅ 생성자 간 호출이 필요한 이유

하나의 클래스에 생성자가 여러 개 존재할 경우, 중복된 초기화 코드를 줄이고 싶을 때 다른 생성자를 호출할 수 있어요. 또한 자식 클래스가 부모 클래스를 상속받고 있을 경우, 자식 클래스의 생성자가 실행되기 전에 반드시 부모 클래스의 생성자가 먼저 호출돼야 합니다. 이 흐름을 Java에서는 명시적으로 표현하도록 강제하고 있어요.

 

 

📌 this() — 같은 클래스의 다른 생성자 호출

같은 클래스 내에서 다른 생성자를 호출하여 초기화 코드를 재사용할 수 있어요.

public class Member {
    String name;
    int age;

    public Member(String name) {
        this(name, 0);  // 다른 생성자 호출
    }

    public Member(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

⚠️ 주의사항

  • 생성자의 첫 줄에만 위치할 수 있어요.
  • 한 생성자에서 this() 한 번만 호출 가능합니다.

 

📌 super() — 부모 클래스 쪽을 명확히 가리켜요.

자식 클래스가 생성될 때는 항상 부모 클래스의 생성자가 먼저 호출돼야 해요. 부모 클래스에 기본 생성자가 없을 경우, 자식 클래스에서 반드시 super()를 통해 이 과정을 명시해야 해요. 또한 super()를 통해 자식 클래스에서 부모 필드/메서드에 접근할 수 있어요.

 

⚠️ 주의사항

  • super()도 마찬가지로 생성자의 첫 줄에만 사용할 수 있어요.
  • 자식 클래스는 객체를 만들기 전에 부모부터 초기화해야 해요. Java는 이를 강제합니다.
  • 만약 부모 클래스에 기본 생성자가 없을 경우, 자식 클래스에선 super를 통해 부모 클래스를 초기화해야 합니다.

🔸 예제: 부모 생성자 호출

class Animal {
    String type;

    public Animal(String type) {
        this.type = type;
    }
}

class Dog extends Animal {
    public Dog() {
        super("Dog");  // 부모 클래스 생성자 호출
    }
}

🔸 예제: 부모 메서드 호출

class Parent {
    void greet() {
        System.out.println("Hello from Parent");
    }
}

class Child extends Parent {
    void greet() {
        super.greet();  // 부모 메서드 호출
        System.out.println("Hello from Child");
    }
}

// 출력
// Hello from Parent  
// Hello from Child

🔸 예제: 부모 필드에 접근

class Parent {
    String name = "Parent";
}

class Child extends Parent {
    String name = "Child";

    void printNames() {
        System.out.println(name);        // Child
        System.out.println(super.name);  // Parent
    }
}

 

✅ 메모리 구조 관점에서의 이해

Child c = new Child();

이렇게 객체를 생성하면:

  • Child 객체가 힙(heap)에 생성되지만
  • 그 안에는 부모 클래스의 필드와 메서드도 포함되어 있어요.
  • 그래서 super는 그 부모 부분을 가리키고, this 전체 객체를 가리키는 거예요.
⚠️ this()와 super()는 동시에 쓸 수 있을까?

this()와 super() 두 키워드 모두 생성자 안에서 첫 번째 줄에만 사용 가능하다는 제약이 있습니다. 때문에 동일한 생성자 안에서는 둘 중 하나만 사용할 수 있어요.
public class Child extends Parent {
    public Child() {
        this();     // ✅ 첫 줄 OK
        super();    // ❌ 두 번째 줄에 사용하면 컴파일 에러 발생
    }
}​