상위 클래스가 정의한 것과 똑같은 시그니처의 메서드를 하위 클래스에서 다시 정의한 것
=> 호출 시, 재정의한 메서드가 실행이 됨
특징
컴파일 타임에 그 인스턴스 타입이 무엇인가는 상관없이 동적으로(가장 하위에서 정의한) 선택된다.
다중정의(overloading, 오버로딩)
: 같은 이름을 가지지만 서로 다른 매개변수 형식을 가지고 있는 메서드를 여러 개 정의하는 것.
특징
다중정의된 메서드들 중 어느 걸 호출할지는 컴파일 타임에 정해진다.(정적으로 선택됨)
=> 컴파일타임의 매개변수 타입을 기준으로 호출이 된다.
재정의와 같이 동작하게 하기 위해서는 정적 메서드인 instanceof로 명시적으로 검사하도록 한다.
public static 5tring classify(Collection<?> c) {
retu rn c instanceof 5et ? "집합" : c instanceof List ? "리스트" : "그 외";
}
어떤 다중정의의 메서드가 호출될지 확실하지 않다면(안전하고 보수적으로 가려면)
매개변수 수가 같은 다중정의는 피해야한다. (특히 가변인수 사용 메서드)
다중 정의 대신 메서드 이름을 다르게 주는 것이 낫다.
ex) ObjectOutputStream 클래스의 write 메서드를 다중정의가 아닌 writeBoolean(boolean), writelnt(int) , writeLong(long)으로 주는 것
생성자의 경우 이름이 무조건 같아야 하므로 다중정의를 피할 수 없지만 대안으로 정적 팩터리 사용이 가능하다.
여러 생성자가 같은 수의 매개변수를 받아야 하는 경우라도
매개변수 중 하나 이상이 근본적으로 다르다(radically different)면
즉, 두 타입의 null이 아닌 값을 서로 어느 쪽으로든 형변환할 수 없다면
어느 다중정의 메서드를 호출할지가 매개변수들의 런타임 타입만으로 결정된다.
=> 컴파일타임 타입에는 영향을 받지 않게 되고 흔란을 주는 주된 원인이 사라진다.
다중 정의 시, 혼란 주는 경우 (TODO 조금 더 채워넣을 예정)
제네릭, 오토박싱
자바 4까지는 모든 기본 타입이 모든 참조 타입과 근본적으로 달랐지만 자바 5부터는 List 인터페이스가 취약해졌다.
자바 8에서 도입된 람다, 메서드 참조
요약
일반적으로 매개변수가 같을 때는 다중정의를 피하고
피할 수 없다면 헷갈릴 만한 매개변수는 형변환 해서 "근본적으로" 다른 다중정의 메서드가 선택되도록 해야한다.
그래야 다중정의 메서드나 생성자를 효과적으로 사용할 수 있고 의도대로 동작시킬 수 있다.
메서드 재정의(override, 오버라이드)
상위 클래스가 정의한 것과 똑같은 시그니처의 메서드를 하위 클래스에서 다시 정의한 것 => 호출 시, 재정의한 메서드가 실행이 됨
다중정의(overloading, 오버로딩)
: 같은 이름을 가지지만 서로 다른 매개변수 형식을 가지고 있는 메서드를 여러 개 정의하는 것.
=> 컴파일타임의 매개변수 타입을 기준으로 호출이 된다.
instanceof
로 명시적으로 검사하도록 한다.매개변수 수가 같은 다중정의는 피해야한다. (특히 가변인수 사용 메서드)
writeBoolean(boolean), writelnt(int) , writeLong(long)
으로 주는 것매개변수 중 하나 이상이 근본적으로 다르다(radically different)면
즉, 두 타입의 null이 아닌 값을 서로 어느 쪽으로든 형변환할 수 없다면
어느 다중정의 메서드를 호출할지가 매개변수들의 런타임 타입만으로 결정된다. => 컴파일타임 타입에는 영향을 받지 않게 되고 흔란을 주는 주된 원인이 사라진다.
요약
일반적으로 매개변수가 같을 때는 다중정의를 피하고
피할 수 없다면 헷갈릴 만한 매개변수는 형변환 해서 "근본적으로" 다른 다중정의 메서드가 선택되도록 해야한다.
그래야 다중정의 메서드나 생성자를 효과적으로 사용할 수 있고 의도대로 동작시킬 수 있다.