자바/자바

(자바) 자바의 신 day4 - 상속 기본 (생성자 규칙 + 오버라이딩)

불광동 물주먹 2025. 6. 24. 00:16

1. 상속 시 생성자 규칙

기본 규칙

  • 자식 클래스의 생성자에서는 무조건 부모 생성자를 먼저 호출해야 한다.
  • 명시하지 않으면 컴파일러가 자동으로 super();를 추가함
  • 그런데 부모 클래스에 기본 생성자가 없으면, 자동 super(); 호출이 불가능하므로 컴파일 에러 발생

예시 1: 부모에 기본 생성자 없을 때

class Parent {
    public Parent(String name) {}  // 기본 생성자 없음
}

class Child extends Parent {
    // 컴파일 에러! super() 자동 삽입 → 오류
    public Child() {}
}

해결법:

  1. 부모에 기본 생성자 추가
  2. 자식에서 명시적으로 super("값") 호출
class Child extends Parent {
    public Child() {
        super("default");
    }
}

요약


 

상황 해결 방법
부모 기본 생성자 없음 자식에서 super(매개변수) 호출
부모 기본 생성자 있음 자식에 super(); 자동 삽입됨
 

2. 메서드 오버라이딩 (Overriding)

규칙

  • 부모 클래스의 메서드와 시그니처(이름, 매개변수, 반환형) 가 동일해야 오버라이딩
  • 오버라이딩된 메서드는 자식의 것이 우선 호출된다 (동적 바인딩)
  • 부모 메서드를 오버라이딩하면서 super.methodName()으로 명시적 호출은 가능하다
class Parent {
    public void greet() {
        System.out.println("부모 인사");
    }
}

class Child extends Parent {
    @Override
    public void greet() {
        System.out.println("자식 인사");
    }
}

실행 결과

Parent p = new Child();
p.greet();  // 출력: 자식 인사

동적 바인딩: 실행 시점에 객체 타입 기준으로 메서드 결정


3. 오버라이딩 시 접근 제어자 제한

  • 오버라이딩 시 부모 메서드보다 더 좁은 접근 제어자로는 불가능
  • 이유: 부모 타입으로 참조했을 때, 접근 불가능한 메서드가 되면 다형성 위반

허용/불허 예


 

부모 접근자 자식 접근자 허용 여부
public public ✅ 허용
protected public ✅ 허용
protected protected ✅ 허용
public protected ❌ 에러
protected private ❌ 에러
private public / protected / private ✅ 가능 (아예 오버라이딩이 아님)
 
class Parent {
    public void greet() {}
}

class Child extends Parent {
    @Override
    protected void greet() {}  // ❌ 컴파일 에러: 접근자 좁아짐
}

4. 참고: @Override와 컴파일 안정성

  • @Override는 컴파일러에게 "이 메서드는 부모를 오버라이딩하는 것"이라고 명시
  • 실수로 시그니처가 틀려도 컴파일러가 잡아줌
@Override
public void greet(String name) {}  // ❌ 부모에 greet(String name) 없으면 컴파일 에러