어제 오늘 내일

[Java] 메서드 오버라이딩 규칙 정리 본문

IT/Java

[Java] 메서드 오버라이딩 규칙 정리

hi.anna 2025. 12. 28. 09:21

메서드 오버라이딩(Overriding)은 자식 클래스에서 부모 클래스의 메서드를 재정의하여
자식 클래스에 맞는 동작을 구현하는 기능입니다.
다형성의 핵심 요소이며 객체지향에서 매우 중요한 개념입니다.

이 글에서는 오버라이딩을 사용할 때 반드시 지켜야 하는 규칙을 명확하게 정리합니다.

 

1. 메서드 이름이 같아야 한다

부모 메서드와 동일한 메서드 이름을 가져야 오버라이딩이 성립합니다.

class Parent {
    void hello() {}
}

class Child extends Parent {
    @Override
    void hello() {} // 이름 동일
}

 

 

2. 매개변수(파라미터) 타입과 개수가 같아야 한다

메서드 시그니처(이름 + 매개변수)가 완전히 같아야 오버라이딩입니다.
조금이라도 다르면 오버로딩(Overloading)이 됩니다.

void hello(String msg); // 매개변수 변경 → 오버로딩

 

 

3. 반환 타입이 동일하거나 더 좁은 타입(공변 반환 타입)이어야 한다

Java는 오버라이딩 시 동일하거나, 더 구체적인(return type covariance) 반환 타입을 허용합니다.

class Parent {
    Animal getAnimal() { return new Animal(); }
}

class Child extends Parent {
    @Override
    Dog getAnimal() { return new Dog(); } // ✔ 더 구체적인 타입
}

 

 

4. 접근 제어자(Access Modifier)는 더 넓게는 가능, 더 좁게는 불가

부모보다 제한적인 접근 제어자를 쓰면 오류가 발생합니다.

부모  자식 가능 자식 불가
public public, protected, default private
protected protected, public private, default
default default, protected, public private
private 오버라이딩 자체가 불가 -

예:

class Parent {
    protected void hello() {}
}

class Child extends Parent {
    @Override
    public void hello() {} // ✔ 가능 (범위 확장)
}

 

 

5. 예외(Exception)는 더 좁은 범위로만 던질 수 있다

오버라이딩 메서드는 부모 메서드보다 더 넓은 예외를 던질 수 없습니다.

void work() throws Exception {}

부모가 Exception을 던지면 자식은:

@Override
void work() throws IOException {} // ✔ 더 좁은 예외 허용

하지만:

@Override
void work() throws Throwable {} // ❌ 더 넓은 범위 예외 불가

 

 

6. static 메서드는 오버라이딩 불가 (숨김: Hiding)

static 메서드는 클래스 소속 메서드이므로 오버라이딩할 수 없습니다.

class Parent {
    static void hello() {}
}

class Child extends Parent {
    static void hello() {} // ✔ 가능하지만 오버라이딩이 아니라 '숨김(Hiding)'
}

 

 

7. private 메서드는 오버라이딩 불가

private 메서드는 상속되지 않기 때문에 오버라이딩 대상 자체가 아닙니다.

class Parent {
    private void secret() {}
}

class Child extends Parent {
    void secret() {} // ❌ 오버라이딩 아님 → 완전히 새로운 메서드
}

 

 

8. @Override 애너테이션 사용을 강력히 추천

@Override는 컴파일러가 오버라이딩이 맞는지 검사해주므로 실수를 예방할 수 있습니다.

@Override
void hello() {}

오타나 매개변수 불일치가 있을 경우 즉시 컴파일 오류가 나므로 매우 유용합니다.

 

9. 전체 예제

class Animal {
    void sound() {
        System.out.println("동물 소리");
    }
}

class Dog extends Animal {
    @Override
    void sound() { // 오버라이딩
        System.out.println("멍멍");
    }
}

사용:

Animal a = new Dog();
a.sound(); // 멍멍

설명

  • 오버라이딩된 메서드는 실제 객체 타입(Dog) 기준으로 실행됨

 

10. 오버로딩 vs 오버라이딩 차이 정리

구분 오버라이딩 오버로딩
목적 부모 메서드 재정의 같은 이름 메서드 여러 개 생성
조건 이름·매개변수 동일 매개변수 다르면 됨
반환 타입 동일 또는 더 구체적 아무 타입 가능
관련 개념 다형성 코드 편의성

 

11. 정리

  • 오버라이딩은 “부모의 메서드를 자식이 재정의하는 것”
  • 메서드 이름, 매개변수(시그니처)는 완전히 같아야 함
  • 접근 제어자는 더 넓게만 변경 가능
  • 반환 타입은 동일하거나 더 구체적
  • private, static 메서드는 오버라이딩 불가
  • @Override 사용하면 실수 방지 가능

 

 

반응형
Comments