오버로딩과 오버라이딩

김세빈·2025년 4월 9일

CS

목록 보기
8/22

Java 메서드 오버로딩(Overloading) vs 오버라이딩(Overriding)

  • 오버로딩: 같은 이름의 메서드를 매개변수 시그니처만 다르게 하여 여러 개 정의 → 컴파일 타임(정적) 다형성.
  • 오버라이딩: 상위 클래스/인터페이스의 메서드를 동일한 시그니처로 재정의 → 런타임(동적) 다형성.
  • static·final 메서드는 오버라이딩이 불가(숨김‧은닉만 가능) → 설계 의도를 명확히 해야 한다.

1. 용어 한눈에 보기

개념정의발생 시점핵심 키워드
오버로딩메서드 이름은 같고 매개변수 개수·타입·순서가 다른 메서드를 다중 정의컴파일 타임정적 다형성, 메서드 시그니처
오버라이딩상위 타입의 메서드를 동일 시그니처로 재정의런타임동적 다형성, 가상 메서드 테이블

📝 Tip: 오버로딩은 메서드 선택이 컴파일러 단계에서 결정되고, 오버라이딩은 실행 중 객체의 실제 타입에 따라 결정됩니다.


2. 오버로딩: "과적(Over‑load)"의 의미

2‑1. 왜 필요한가?

  • 가독성: printInt(), printDouble() 대신 print() 하나로 통일
  • 유연성: API 사용자가 매개변수에 따라 자연스럽게 호출 가능

2‑2. 코드 예제

class Calculator {
    int add(int a, int b) {
        return a + b;
    }

    // 매개변수 개수 다름
    int add(int a, int b, int c) {
        return a + b + c;
    }

    // 매개변수 타입 다름
    double add(double a, double b) {
        return a + b;
    }
}

⚠️ 주의: 반환형만 다른 메서드는 오버로딩이 되지 않는다. 컴파일러는 반환형으로만 메서드를 구분하지 않는다.


3. 오버라이딩: "재정의(Re‑define)"의 힘

3‑1. 핵심 포인트

  • @Override 애너테이션으로 컴파일 타임 검증
  • 접근 제어자는 동일 또는 더 넓은 범위만 허용
  • 예외는 동일 또는 더 구체적한(좁은) 예외만 선언 가능

3‑2. 코드 예제

class Animal {
    void speak() {
        System.out.println("...");
    }
}

class Dog extends Animal {
    @Override
    void speak() {
        System.out.println("멍멍!");
    }
}

// 실행
Animal a = new Dog();
a.speak(); // 멍멍! — 런타임에 Dog.speak() 선택

4. static & final 메서드는 왜 오버라이딩이 안 될까?

키워드오버라이딩 여부이유
static(메서드 숨김 only)클래스 단위로 바인딩 → 인스턴스에 귀속되지 않음
final상속은 가능하지만 변경 금지 의도 → JIT 인라이닝 최적화 가능

4‑1. static 메서드 숨김 예시

class Parent {
    static void hello() { System.out.println("Parent"); }
}
class Child extends Parent {
    static void hello() { System.out.println("Child"); } // 숨김
}
Parent p = new Child();
p.hello(); // Parent — 참조 타입 기준

🔍 메서드 숨김(Hiding): 오버라이딩과 달리 참조 변수의 타입에 따라 메서드가 결정된다.

4‑2. final 메서드 예시

class Base {
    final void cannotChange() {}
}
class Sub extends Base {
    // 컴파일 오류: cannot override final method
    // void cannotChange() {}
}

5. 베스트 프랙티스

  1. @Override를 습관처럼 붙여라 → 실수 방지
  2. 오버로딩 시, 모호성을 피하기 위해 매개변수 수/타입을 명확히 구분하라.
  3. 공통 로직을 static으로 올릴 때는 은닉(hiding)으로 오해하지 않도록 메서드명을 차별화하거나, Utility 클래스로 분리하라.
  4. 상속 설계 시 변경될 가능성이 있는 메서드만 protected/abstract로 열어두고, 변경이 필요 없는 메서드는 final로 고정해 안전성 확보.

6. 결론

  • 오버로딩오버라이딩은 다형성을 구현하는 두 축이다.
  • staticfinal 키워드는 오버라이딩을 제한하여 의도를 명확히 하고 성능을 최적화한다.
  • 올바른 사용은 코드의 유연성안정성을 동시에 높인다.

참고 자료

  • Effective Java, Item 52: 오버로딩된 메서드의 사용은 신중히 하라
  • Effective Java, Item 38: 객체의 상태를 캡슐화하라

0개의 댓글