정의
오버라이딩은 부모 클래스에서 정의된 메서드를 자식 클래스에서 재정의하는 것을 말함
이를 통해 상속받은 메서드의 동작을 자식 클래스에 맞게 변경할 수 있음
- 메서드의 시그니처(메서드 이름, 매개변수, 반환 타입)가 부모와 동일해야 함
- 다형성을 활용해 자식 객체를 부모 타입으로 다룰 때, 자식 클래스의 메서드가 실행됨
- 상속받은 메서드를 자식 클래스에서 재정의하여 유연한 코드 확장을 가능케 하며, 이를 통해 다형성 구현 및 코드 재사용성 향상
장점
1. 다형성(Polymorphism) 구현:
부모 클래스를 참조 타입으로 사용하더라도 자식 클래스의 메서드가 호출됨
2. 코드 재사용성 향상:
부모 클래스의 기본 기능을 유지하면서 자식 클래스에 맞게 기능을 확장
3. 유연한 확장:
부모 클래스의 기본 구현이 아닌, 상황에 맞는 메서드 구현이 가능해짐
사용법
1. 기본 사용법
자식 클래스에서 부모의 메서드를 재정의할 때 @Override 어노테이션을 붙이는 것이 좋음
해당 어노테이션은 컴파일러에게 오버라이딩을 명확하게 알리고, 잘못된 메서드 재정의를 방지
class Animal {
void sound() {
System.out.println("동물이 소리를 냅니다.");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("개가 멍멍 짖습니다.");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog(); // 부모 타입으로 자식 객체를 참조
myDog.sound(); // 출력: 개가 멍멍 짖습니다.
}
}
2. 오버라이딩의 조건
1) 메서드 시그니처가 동일해야 함:
- 메서드 이름, 매개변수 타입과 개수, 반환 타입이 부모와 동일해야 함
2) 접근 제어자:
- 오버라이딩된 메서드의 접근 제어자는 부모 메서드보다 같거나 더 넓은 범위여야 함
- 부모가 protected이면, 자식은 protected나 public으로 가능하지만 private은 불가능
3) 예외 처리:
- 자식 메서드는 부모 메서드가 던지는 예외보다 더 적거나 같은 종류의 예외를 던져야 함
오버라이딩과 오버로딩의 차이점
| 항목 |
Overriding |
Overloading |
| 목적 |
부모 메서드를 재정의 |
같은 이름의 메서드를 여러 개 정의 |
| 메서드 시그니처 |
부모와 동일해야 함 |
매개변수 타입 또는 개수가 다름 |
| 클래스 관계 |
상속 관계에서만 가능 |
같은 클래스 내에서 가능 |
| 런타임 / 컴파일타임 |
런타임 시 결정 (다형성) |
컴파일타임에 결정 |
super 키워드를 사용한 부모 메서드 호출
오버라이딩된 메서드 내에서 부모 클래스의 원래 메서드를 호출할 때는 super 키워드를 사용
class Animal {
void sound() {
System.out.println("동물이 소리를 냅니다.");
}
}
class Dog extends Animal {
@Override
void sound() {
super.sound(); // 부모 클래스의 sound() 호출
System.out.println("개가 멍멍 짖습니다.");
}
}
public class Main {
public static void main(String[] args) {
Dog myDog = new Dog();
myDog.sound();
}
}
출력:
동물이 소리를 냅니다.
개가 멍멍 짖습니다.
오버라이딩과 final 키워드
final로 선언된 메서드는 오버라이딩할 수 없음
class Animal {
final void sound() {
System.out.println("이 메서드는 오버라이딩할 수 없습니다.");
}
}
class Dog extends Animal {
// 컴파일 오류: 부모 클래스의 final 메서드는 오버라이딩할 수 없습니다.
void sound() {
System.out.println("개가 멍멍 짖습니다.");
}
}
오버라이딩과 추상 클래스 / 인터페이스
- 추상 클래스:
추상 메서드는 자식 클래스에서 반드시 오버라이딩해야 함
- 인터페이스:
인터페이스의 메서드도 구현 클래스에서 오버라이딩해야 함
abstract class Animal {
abstract void sound(); // 추상 메서드
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("개가 멍멍 짖습니다.");
}
}
비고
1. 목, 토요일 오전에 TIL 작성뿐만 아니라 추상클래스에 대해서도 꼭 다시 읽어보기. 그리고 Java 책들에서도 이 부분 찾아봐야겠다.
2. 오버라이딩된 메서드에서 부모 클래스 메서드가 꼭 필요한 경우에 대해서도 알아보고 읽어 보았다. 부모 클래스의 기본 동작을 유지하면서 확장하거나, 중요한 로직을 재사용할 때 그렇게 된다고 한다. super 키워드를 활용해서 코드 중복을 줄이고, 유지보수성을 높인다.
레퍼런스
1. 멘토링 강의, 구글링, 코드 예시의 경우 ChatGPT