[이펙티브 자바] 아이템 52. 다중정의는 신중히 사용하라

June·2022년 3월 31일
0

[이펙티브자바]

목록 보기
47/72

다중정의

"집합", "리스트", "그 외"를 차례로 출력하기를 예상했지만, 실제로 수행해보면 "그 외"만 세 번 출력한다.

다중정의(오버로딩)된 세 classify 중 어느 메서드를 호출할지가 컴파일타임에 정해진기 때문이다. 컴파일 타임에는 for 문 안에 c는 항상 Collection<?> 타입이다. 런타임에는 타입이 달라지지만, 영향을 주지 못한다.

이렇게 예상을 빗나가게 행동하는 이유는 재정의한 메서드는 동적으로 선택되고, 다중정의한 메서드는 정적으로 선택되기 때문이다.

재정의

다형성을 이용해 메서드를 재정의한 것은 해당 객체의 런타임 타입이 어떤 메서드를 호출할지 기준이 된다. 복습 차원에서 적자면 메서드 재정의란 상위 클래스가 정의한 것과 똑같은 시그니처의 메서드를 하위 클래스에서 다시 정의한 것을 말한다. 메서드를 재정의한 다음 '하위 클래스의 인스턴스'에서 그 메서드를 호출하면 재정의한 메서드가 실행된다.

오버로딩과 오버라이딩 차이에 대해 질문 받은 적이 있다. 그때는 단순히 오버라이딩은 상위 클래스 메서드 재정의이고 오버로딩은 메서드 시그니처 차이에 따라 같은 이름의 메서드를 정의하는 것이라고 헀다. 근본적으로 어느 런타임에 정해지는지 차이가 있네.

컴파일타임 타입이 모두 Wine인 것에 무관하게 가장 하위에서 정의한 재정의 메서드가 실행되었다.

대안

다중정의가 혼동을 일으키는 상황은 피하자. 안전하게 매개변수 수가 같은 다중정의는 만들지 말자. 가변인수를 사용하는 메서드라면 다중정의를 아예 하지 말자 (아이템 53). 다중정의하는 대신 메서드 이름을 다르게 지어주는 대안이 있다.

예외

생성자는 이름을 다르게 지을 수 없으니 두 번째 생성자부터 무조건 다중정의가 된다. 하지만 정적 팩터리를 대안으로 쓸 수도 있고, 애초에 생성자는 재정의 할 수 없으니 다중정의와 재정의가 혼용될 가능성이 없다.

매개변수 수가 같은 다중정의 메서드가 많더라도, 그중 어느 것이 주어진 매개변수 집합을 처리할지 명확히 구분된다면 헷갈릴 일은 없다.

0개의 댓글