개발자는 기록이 답이다

🐙 오버로딩과 오버라이딩의 차이점 본문

언어/Java

🐙 오버로딩과 오버라이딩의 차이점

slow-walker 2023. 12. 21. 15:35

 

 

오버로딩과 오버라이딩은 Java에서 다형성을 구현하는 두 가지 주요 메커니즘이다.

 

  위치 시그니처 반환 타입
오버라이딩 상속 관계에서 부모 클래스의 메소드를 자식 클래스에서 재정의 메소드 이름과 매개변수의 타입 및 개수가 일치해야 함 반환 타입까지 동일해야 함
오버로딩 같은 클래스 내에서 발생 메소드 이름이 같고, 매개변수의 타입 또는 개수가 달라야 함 반환 타입이 달라도 됨
 
  • 오버라이딩 : 상속 관계에서 부모클래스에서 선언된 메소드를 하위클래스에서 가져와 구현할때 사용
class Animal {
    void makeSound() {
        System.out.println("동물 소리");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("멍멍");
    }
}
  • 오버로딩 : 하나의 클래스 내에서 동일한 메소드명을 가진 함수 여러개를 매개변수 타입이나 매개변수 개수를 다르게 하여 재정의
    • 메소드의 시그니처가 달라야 한다고 표현한다
    • 시그니처 : 메소드의 이름, 매개변수의 타입, 매개변수의 개수로 구성됨
class OverloadExample {
    // 매개변수 타입이 다른 오버로딩
    void printValue(int x) {
        System.out.println("정수 값: " + x);
    }

    void printValue(double x) {
        System.out.println("실수 값: " + x);
    }

    // 매개변수 개수가 다른 오버로딩
    void printValue(String message, int x) {
        System.out.println(message + ": " + x);
    }
}

오버로딩에서 매개변수 타입 외에도 다른 조건이 적용있을까?

매개변수의 타입이나 개수 이외에는 다른 조건으로 오버로딩을 할 수 없다.

메소드의 반환 타입이나 접근 제어자만 다른 경우에는 오버로딩이 성립되지 않는다. 

 

아래 코드는 오버로딩이 아닌 중복 정의의 코드 예시이다.

int calculate(int a, int b) {
    return a + b;
}

double calculate(int a, int b) {
    return (double) (a + b);
}

오버로딩을 사용할 때 주의 할 점?

  • 메소드 시그니처가 중요하므로 매개변수의 타입과 개수를 명확하게 구분해야 한다.
  • 오버로딩은 메소드 호출 시 컴파일러가 적절한 메소드를 선택할 수 있게 하는 편리한 기능이지만, 혼동을 초래할 수 있으므로 신중하게 사용해야 한다.

오버라이딩에서의 반환 타입이 왜 엄격하게 검증되어야 할까?

 
자식 클래스에서는 부모 클래스의 메소드를 "재정의"하므로, 동일한 시그니처와 반환 타입이 유지되어야 한다.
 

그 이유는 Java에서는 반환 타입의 엄격한 일치를 요구하는 이유는 다형성과 호환성을 보장하기 위함이다.
다형성을 사용하기 위해서는 부모 클래스 타입의 변수로 자식 클래스의 객체를 참조할 수 있어야 하는데, 반환 타입이 다르면 이러한 다형성이 깨질 수 있다.

 

또한 컴파일 시에 반환 타입이 일치하는 지 확인함으로써 런타임에 발생할 수 있는 에러를 방지할 수 있다.

class Animal {
    Animal reproduce() {
        return new Animal();
    }
}

class Dog extends Animal {
    // 컴파일 에러: 반환 타입이 일치하지 않음
    @Override
    Dog reproduce() {
        return new Dog();
    }
}

반환 타입이 다른 경우에는 어떤 문제가 발생할 수 있을까?

 

  •  다형성 상실
    • 반환 타입이 다르면 자식 클래스의 메소드를 사용할 때 형 변환에 문제가 발생할 수 있다.
    • 반환 타입이 일치하지 않으면 부모 클래스 타입으로 자동 형 변환이 어려워진다.
  • 런타임 에러
    • 일치하지 않는 반환 타입으로 오버라이딩된 메소드를 호출하면 런타임에 ClassCastException이 발생할 수 있다.
      이는 코드의 안정성을 해칠 수 있다.