Java 상속 - 메소드 오버라이딩
상속하고 있는 부모 타입의 기능을 내 메소드로 재정의 한다.
이전 시간에 자동차의 Car.move() 호출 시 "차 이동하기~" 라고 출력하였다.
그리고 상속하고 있는 ElectricCar 전기차는 move() 메소드를 호출한 경우 "전기차 이동하기~" 라고 변경하고 싶은 경우가 있다.
부모에게 상속 받은 기능을 재정의 하는 것을 메소드 오버라이딩(Overriding)이다.
예제 코드 작성하기
이전 시간에 작성한 코드를 불려오고 ElectricCar.java 코드만 변경한다.
src
└Student
└ex3
├HydrogenCar.java
├ElectricCar.java (*)
├GasCar.java
├Car.java
└CarMain.java
Car.java
- 오버라이딩은
@Override
어노테이션을 선언해주었다.
package Student.ex3;
public class ElectricCar extends Car {
@Override
public void move() {
System.out.println("전기차 이동하기~");
}
public void charge() {
System.out.println("차 충전하기~");
}
}
MainCar.java
package Student.ex3;
public class CarMain {
public static void main(String[] args) {
System.out.println("*==전기차==*");
ElectricCar electricCar = new ElectricCar();
electricCar.move();
System.out.println("*==가솔린차==*");
GasCar gasCar = new GasCar();
gasCar.move();
}
}
출력 결과
*==전기차==*
전기차 이동하기~
*==가솔린차==*
차 이동하기~
부모 타입인 Car 의 move() 기능을 수행하지 않는다. 메소드 이름은 같지만 새로운 기능으로 ElectricCar만의 move() 메소드가 호출한 것이다.
메소드가 재정의 되어 ElectricCar.move() 호출 시 전기차만의 메시지 문구가 출력하였다.

@Override
프로그램이 읽을 수 있는 주석이다. 프로그램이 읽을 수 있기 때문에 특별한 동작을 한다.
- 상위 클래스의 메소드를 오버라이드 하는 것을 나타낸다.
- 오버라이딩한 메소드 위에 @Override 어노테이션을 붙어야 한다.
- 컴파일러가 @Override 어노테이션으로 메소드가 정확히 오버라이드 되었는지 확인한다. 오버라이드 조건 불만족한 경우 컴파일 오류를 발생한다. 실수로 인한 오버라이딩을 방지한다.
- move() 메소드를 재정의 하였는데, 부모 클래스에서 move() 가 없다면 컴파일 오류가 발생한다.
- 이 기능은 필수는 아니나 명확한 코드로 붙어주도록 한다.
상속 메모리 구조
오버라이드한 move() 메소드를 살펴본다.

- electricCar.move() 호출
- 호출한 electricCar 타입이 ElectricCar 이고, 인스턴스 내부에서도 동일한 타입에서 시작한다.
- ElectricCar 타입에 move() 메소드가 있다. 메소드를 찾았으므로 부모 타입을 찾지 않는다.
오버로딩과 오버라이딩
오버라이딩과 오버로딩을 혼동될 수 있으므로 정리한다.
메소드 오버로딩
메소드 이름이 같지만, 파라미터를 다르게 정의한 것이 메소드 오버로딩(Overloading)이다. 오버로딩 뜻은 과적으로, 같은 이름의 메소드를 여러개 정의되어 과적되었다 뜻으로 사용한다.
메소드 오버라이딩
메소드 오버라이딩은 하위 클래스에서 상위 클래스로 메소드 재정의 한 것을 말한다.
상속 관계에서만 사용하고, 부모의 기능을 자식에서 다시 정의한 것이다.
오버라이딩 뜻은 가파른 길을 넘어서 타는 것을 말한다. 부모의 기존 기능을 넘어 나만의 새로운 기능을 덮어쓰는 것으로 이해한다.
오버라이딩 조건
메소드 오버라이딩은 시그니쳐 검증이 많다.
- 메소드 이름: 메소드 이름이 같아야 함
- 메소드 파라미터: 파라미터 타입, 순서, 개수가 동일해야 함
- 메소드 반환 타입: 동일한 반환 타입이 있어야 한다.
- 접근 제어자: 접근 제어자는 상위 클래스 메소드보다 더 제한을 두어선 안된다.
- 예: protected 상위 클래스 상속 받아 하위 클래스은 private, default 접근제어자를 사용하지 못한다.
- protected 상위 클래스보다 개방적인 public, protected 접근 제어자로 오버라이딩한다.
- 예외(Exception): 오버라이딩 메소드는 부모 클래스보다 많은 체크 예외를 throws 할 수 없다.
- 더 적거나 같은 수의 예외 또는 하위 타입의 예외를 선언할 수 있다.
- static, final, private 키워드: 해당 메소드로 선언된 메소드는 오버라이딩 할 수 없다.
- static 클래스 레벨의 작동으로 인스턴스 레벨로 오버라이딩 할 수 없다.
상속 관계 없이 클래스 이름을 통해 직접 접근하도록 한다. - final 키워드로 정의한 메소드는 오버라이딩 사용 불가하다.
- private 메소드는 외부에서 접근 거부로 하위 클래스에서는 볼 수 없다. 오버라이딩이 불가하다.
- static 클래스 레벨의 작동으로 인스턴스 레벨로 오버라이딩 할 수 없다.
- 생성자 오버라이딩: 생성자 대상으로 오버라이딩을 할 수 없다.