프로젝트 중 느낀 자바 기초의 부족함을 보완하고자 핵심 주제를 순차적으로 복습할 예정입니다.
자바 코어 → 자바 스레드 → 자바 OOP → 자바의 예외 → 자바의 컬렉션 → 최대 절전 모드 순으로 정리할 예정입니다.
메서드 오버로딩과 오버라이딩
- 메서드 오버로딩과 메서드 재정의의 차이점은 무엇입니까?
- 기본 메소드를 재정의할 수 있습니까?
- 재정의된 메서드의 슈퍼클래스 버전을 호출하는 방법은 무엇입니까?
- 메서드가 재정의되는 것을 어떻게 방지합니까?
메서드 오버로딩과 메서드 재정의의 차이점은 무엇입니까?
메서드 오버로딩(Overloading)은 하나의 클래스 내에서 같은 이름의 메서드를 매개변수의 수나 타입을 다르게 하여 여러 개 정의하는 것을 의미하며, 컴파일 시점에 어떤 메서드가 호출될지 결정됩니다. 이는 컴파일 타임에 바인딩되므로 정적 바인딩(static binding)에 해당합니다.
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
}
반면, 메서드 재정의(Overriding)는 상위 클래스에 정의된 메서드를 하위 클래스에서 동일한 시그니처로 다시 구현하는 것으로, 런타임에 어떤 구현이 호출될지 결정되며 동적 바인딩(dynamic binding)에 해당합니다. 오버로딩은 다형성과 직접적인 관련은 없으나, 오버라이딩은 상속 구조 내에서 메서드를 재정의하여 사용하기 때문에 다형성을 실현할 수 있습니다.
class Animal {
public void speak() {
System.out.println("Animal sound");
}
}
class Dog extends Animal {
@Override
public void speak() {
System.out.println("Bark");
}
}
//
Animal animal = new Dog();
animal.speak(); // 출력: Bark
기본 메소드를 재정의할 수 있습니까?
네. Java에서 인터페이스의 default 메서드는 구현 클래스에서 자유롭게 오버라이딩할 수 있습니다. default 메서드는 Java 8 이후부터 인터페이스가 구현 코드를 포함할 수 있도록 허용된 특수한 형태입니다. 이는 기존 인터페이스에 새로운 메서드를 추가해도 이를 구현한 클래스가 깨지지 않도록 하기 위해 만들어졌습니다. 이전에는 인터페이스에 메서드를 추가하면 모든 구현 클래스가 반드시 그 메서드를 직접 구현해야 해서 호환성 문제가 발생했는데, 이를 해결하기 위해 도입된 것입니다. 다만 인터페이스는 원래 행위만 정의하고 구현은 가지지 않는다는 원칙이 있었기 때문에, 잘못 사용하면 추상 클래스처럼 역할이 모호해질 수 있다는 점은 주의해야 합니다. 또한 다중 상속된 인터페이스에 동일한 이름의 default 메서드가 있으면 이를 구현 클래스에서 직접 충돌을 해결해줘야 하는 번거로움이 있습니다.
interface Animal {
default void sound() { System.out.println("Animal sound"); }
}
class Dog implements Animal {
@Override
public void sound() { System.out.println("Bark"); } // 재정의 가능
}
재정의된 메서드의 슈퍼클래스 버전을 호출하는 방법은 무엇입니까?
슈퍼클래스의 메서드를 호출하는 방법은 하위 클래스가 상위 클래스의 메서드를 오버라이딩한 경우, super 키워드를 사용해 상위 클래스의 구현을 직접 호출할 수 있습니다.
class Animal {
void sound() { System.out.println("Animal sound"); }
}
class Dog extends Animal {
@Override
void sound() {
super.sound(); // 상위 클래스 메서드 호출
System.out.println("Bark");
}
}
만약 두 개 이상의 인터페이스가 동일한 default 메서드를 정의하였고, 구현클래스에서 인터페이스의 defalut 메서드를 호출하고자 한다면 InterfaceName.super.methodName() 문법을 사용하여 이를 호출할 수 있습니다.
interface Animal {
default void sound() { System.out.println("Animal sound"); }
}
class Dog implements Animal {
@Override
public void sound() {
Animal.super.sound(); // 인터페이스의 기본 메서드 호출
System.out.println("Bark");
}
}
메서드가 재정의되는 것을 어떻게 방지합니까?
Java에서는 메서드 선언에 final 키워드를 사용하여 하위 클래스에서 메서드를 오버라이딩하지 못하도록 할 수 있습니다. final 메서드는 상속은 되지만, 오버라이딩만 차 단하며, 이를 통해 핵심 로직을 보호할 수 있습니다.
class Animal {
final void sound() { System.out.println("Animal sound"); }
}
class Dog extends Animal {
// @Override
// void sound() { } // 컴파일 오류: final 메서드는 오버라이딩 금지
}
'Java' 카테고리의 다른 글
자바 컬렉션 (1) – 기본 개념 (0) | 2025.07.02 |
---|---|
자바 OOP (4) - 인터페이스와 추상 클래스 (0) | 2025.06.17 |
자바 OOP (2) - 상속과 다형성 기초 (0) | 2025.06.17 |
자바 OOP (1) - OOP 기본 개념 및 특징 (0) | 2025.06.17 |
자바 스레드 (4) - 동기화와 잠금 (0) | 2025.06.10 |