[Java] 오버로딩과 오버라이딩

khj·2026년 4월 9일

Java

목록 보기
11/11
post-thumbnail

객체지향 프로그래밍의 핵심인 다형성을 구현하는 두 메커니즘, 오버로딩(Overloading)오버라이딩(Overriding)의 상세 규칙과 내부 동작

1. 오버로딩 (Overloading): 확장과 편의

오버로딩은 같은 이름의 메소드를 '과적'하여 사용자에게 편의성을 제공하는 기술입니다.

  • 컴파일 타임 다형성:
    • 호출할 메소드가 컴파일 시점에 이미 결정되는 정적 바인딩(Static Binding) 방식입니다.
  • 상세 성립 요건:
    • 매개변수 시그니처: 개수, 타입, 또는 타입의 순서가 반드시 달라야 합니다.
    • 반환 타입(Return Type): 반환 타입만 다를 경우, 컴파일러는 이를 구분할 수 없어 에러를 발생시킵니다.
    • 접근 제어자: 제한 없이 자유롭게 설정 가능합니다.
  • 실제 활용: - System.out.println()처럼 다양한 데이터 타입을 하나의 이름으로 출력할 때 사용합니다.
class Logger {
    // 1. 문자열 로그
    void log(String message) { System.out.println("Log: " + message); }

    // 2. 에러 코드와 함께 로그 (오버로딩)
    void log(String message, int errorCode) { 
        System.out.println("Error " + errorCode + ": " + message); 
    }
}

2. 오버라이딩 (Overriding): 변경과 확장

상속받은 부모의 메소드를 자식 클래스의 용도에 맞게 '재정의'하는 기술입니다.

  • 런타임 다형성:
    • 실행 중에 실제 인스턴스의 타입을 확인하여 호출할 메소드를 결정하는 동적 바인딩(Dynamic Binding) 방식입니다.
  • 엄격한 규칙:
    • 메소드 시그니처: 이름, 매개변수, 반환 타입이 부모 클래스의 메소드와 완전히 일치해야 합니다. (Java 5부터는 공변 반환 타입 허용)
    • 접근 제어자: 부모 클래스보다 좁은 범위로 변경할 수 없습니다. (부모가 protected면 자식은 protected나 public만 가능)
    • 예외 처리: 부모 메소드보다 더 넓은 범위의 Checked Exception을 throws 할 수 없습니다.
  • @Override 애노테이션:
    • 컴파일러에게 오버라이딩임을 명시하여, 실수로 시그니처를 다르게 적었을 때 오류를 잡아줍니다.
class Printer {
    void print() { System.out.println("기본 인쇄 모드"); }
}

class ColorPrinter extends Printer {
    @Override
    void print() { 
        // 부모의 동작을 완전히 대체
        System.out.println("컬러 인쇄 모드"); 
    }
}

3. 기술적 세부 비교표

상세 항목오버로딩 (Overloading)오버라이딩 (Overriding)
핵심 목적메소드 호출 시의 편의성 제공부모 클래스 기능의 다변화
바인딩 시점컴파일 타임 (Static)런타임 (Dynamic)
매개변수반드시 다름반드시 같음
반환 타입영향 없음 (같든 다르든 상관없음)반드시 같음
예외 던지기상관 없음부모보다 더 큰 예외 불가
접근 제어자상관 없음부모보다 좁은 범위 불가

4. JVM 내부 동작 원리 (vtable)

JVM은 오버라이딩을 효율적으로 처리하기 위해 내부적으로 Virtual Method Table(vtable)을 사용합니다.

  • vtable의 구조:
    • 모든 클래스는 생성 시 해당 클래스가 가진 메소드 주소를 담은 테이블을 메모리에 올립니다.
    • 자식 클래스가 메소드를 오버라이딩하면, vtable의 해당 인덱스 주소가 부모의 메소드 주소 대신 자식의 메소드 주소로 교체됩니다.
  • 동적 바인딩 과정:
    1. JVM이 인스턴스의 실제 클래스 타입을 확인합니다.
    2. 해당 클래스의 vtable에 접속합니다.
    3. 호출하려는 메소드의 인덱스를 찾아 그곳에 저장된 메모리 주소로 점프하여 실행합니다.
  • 성능 측면:
    • 오버로딩은 컴파일 단계에서 주소가 확정되므로 가장 빠릅니다.
    • 오버라이딩은 실행 중 vtable 참조라는 단계가 추가되지만, 객체지향의 유연성을 확보하는 핵심 비용입니다.

profile
Spring, Django 개발 블로그

0개의 댓글