다중 정의한 메서드는 정적으로 선택된다. (선언된 타입에 집중할 것)
재정의한 메서드는 동적으로 선택된다. (실제 인스턴스의 타입에 따라 달라진다.)
// 코드 52-1 컬렉션 분류기 - 오류! 이 프로그램은 무엇을 출력할까? (312쪽)
public class CollectionClassifier {
public static String classify(Set<?> s) {
return "집합";
}
public static String classify(List<?> lst) {
return "리스트";
}
public static String classify(Collection<?> c) {
return "그 외";
}
public static void main(String[] args) {
Collection<?>[] collections = {
new HashSet<String>(),
new ArrayList<BigInteger>(),
new HashMap<String, String>().values()
};
**for (Collection<?> c : collections) -> main 함수가 아닌 여기서 결정됨**
System.out.println(classify(c));
}
}
다중정의가 혼동을 일으키는 상황을 피하려면!
• 매개변수 수가 같은 다중정의는 만들지 말자. (가변인수는?)
• 다중정의 대신 메서드 이름을 다르게 지어준다. (ObjectOutputStream)
• 생성자를 다중정의해야 할 경우에는 정적 팩터리를 대안으로 활용할 수 있다.
// 수정된 컬렉션 분류기 (314쪽)
public class FixedCollectionClassifier {
**public static String classify(Collection<?> c) {
return c instanceof Set ? "집합" :
c instanceof List ? "리스트" : "그 외";
}**
public static void main(String[] args) {
Collection<?>[] collections = {
new HashSet<String>(),
new ArrayList<BigInteger>(),
new HashMap<String, String>().values()
};
for (Collection<?> c : collections)
System.out.println(classify(c));
}
}
• 서로 다른 함수형 인터페이스라도 같은 위치의 인수로 받아서는 안 된다. (-Xlint:overloads)
• 다중정의한 메서드 기능을 똑같이 만든다**. (잘못된 사례, String의 valueOf(char[]), valueOf(Object)**