1. 서론
Java에서 메서드를 설계할 때 자주 마주치는 두 가지 개념인 Overriding(오버라이딩)과 Overloading(오버로딩)은 이름이 비슷해 혼동하기 쉽지만, 각각 다른 메커니즘과 목적을 가진다.
- Overriding(오버라이딩)은 부모 클래스에 정의된 메서드를 자식 클래스에서 재정의하여 런타임 다형성을 구현하는 방식이다.
- Overloading(오버로딩)은 같은 이름의 메서드를 매개변수 구성이 다르게 여러 개 정의하여 컴파일 시점의 유연성을 제공하는 기법이다.
이 글에서는 두 개념의 차이와 올바른 사용법에 대해 실무 관점에서 정리해 보았다.
2. 본론: Overriding과 Overloading 정리
1) Overriding이란
부모 클래스에 정의된 메서드를 자식 클래스에서 재정의하는 과정을 Overriding이라 한다. 이 방식은 동적 바인딩(런타임 시점에 결정)을 활용하는 특징이 있다.
- 예시 코드
Father 타입의 변수 f로 메서드를 호출할 때 실제 객체가 Son인 경우, Son의 메서드가 실행된다.
런타임에 동적으로 바인딩되는 것이 Overriding의 핵심이다.
class Father {
void print() {
System.out.println("Father's print method");
}
}
class Son extends Father {
@Override
void print() {
System.out.println("Son's print method");
}
}
public class Main {
public static void main(String[] args) {
Father f = new Son(); // 실제 객체는 Son
f.print(); // 출력: Son's print method
}
}
2) Overloading이란
같은 이름의 메서드를 매개변수만 다르게 정의하는 방식을 Overloading이라 한다. 이 경우 컴파일 시점에 어떤 메서드를 호출할지 결정되므로 정적 바인딩이 적용된다.
- 예시 코드
메서드 이름은 동일하지만 매개변수의 타입이 다르기 때문에 컴파일러가 호출할 메서드를 적절히 선택한다.
class MathUtils {
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
}
public class Main {
public static void main(String[] args) {
MathUtils math = new MathUtils();
System.out.println(math.add(3, 5)); // 출력: 8
System.out.println(math.add(3.2, 4.8)); // 출력: 8.0
}
}
3) Overriding과 Overloading의 차이점 정리
| 특성 | Overriding | Overloading |
|---|---|---|
| 정의 | 부모 클래스의 메서드를 자식 클래스에서 재정의하는 방식 | 같은 이름의 메서드를 매개변수 구성이 다르게 여러 개 정의하는 방식 |
| 결정 시점 | 런타임 다형성을 제공하며 실제 객체의 메서드가 실행됨 | 컴파일 시점에 호출할 메서드가 결정되며 정적 바인딩이 적용됨 |
| 메서드 시그니처 및 반환 타입 | 부모 클래스의 메서드와 동일한 시그니처와 반환 타입을 요구함 | 매개변수만 다르면 반환 타입이 달라도 무방함 |
| 메모리 구조 관련 동작 | Method Area에서 런타임에 동적 바인딩이 이루어짐 | 컴파일 시 정적으로 바인딩되는 구조를 갖음 |
4) 실무에서의 활용 예시
- Overriding
- 템플릿 메서드 패턴에서 구체적인 동작을 자식 클래스에 구현할 때 활용
- 의존성 주입 시 런타임에 메서드 동작을 변경할 필요가 있을 때 적용
- Overloading
- 다양한 입력값을 처리하는 유틸리티 메서드에 활용
- 대표적인 예로
System.out.println()메서드를 들 수 있음
3. 결론
- Overriding은 런타임 다형성을 구현하여 실제 객체에 맞는 메서드가 실행되는 특징이 있다.
- Overloading은 컴파일 시점에 호출할 메서드가 결정되며 정적 바인딩을 통해 유연성을 제공한다.
두 개념을 명확히 이해하면 유지보수성과 확장성이 뛰어난 코드를 작성할 수 있다. 실무에서 메서드를 설계할 때 적절히 활용하면 안정적이고 유연한 소프트웨어 구조를 구축하는 데 도움이 될 것이다.
팁: 혼동될 때는 “Overriding은 런타임, Overloading은 컴파일 시점에 결정된다”라는 점을 기억하자.