'오브젝트: 코드로 이해하는 객체지향 설계' 3~4주차
분량 : Ch.11 ~ Ch.15
기간 : 22.5.21 ~ 22.6.4
다형성(Polymorphism)
그리스어에서 '많은'을 의미하는 'poly' + '형태'를 의미하는 'morph'의 합성어로 많은 형태를 가질 수 있는 능력을 의미한다.
=> 여러 타입을 대상으로 동작할 수 있는 코드를 작성할 수 있는 방법
=> 메서드 오버로딩을 사용해 동일한 메서드 이름을 다양하게 사용할 수 있는 것
=> 강제 형변환을 통해 동작
제네릭 프로그래밍과 관련이 높음
예를 들어, List 인터페이스는 보관할 요소의 타입을 임의의 타입 T로 지정해 인스턴스를 생성하는 시점에 T를 구체적인 타입으로 지정할 수 있게 한다.
메시지가 동일하더라도 수신한 객체의 타입에 따라 실제로 수행되는 행동이 달라지는 능력
일반적으로 다형성은 포함 다형성을 의미한다.
// DiscountPolicy를 구현하는 다른 인스턴스로 조합 가능
public class Movie {
private DiscountPolicy discountPolicy;
}
상속의 진정한 목적은 코드 재사용이 아니라 다형성을 위한 서브타입 계층을 구축하는 것이다.
실행할 메서드를 선택하는 방법
- self 참조가 가리키는 메모리로 이동한다. (객체의 현재 상태를 표현하는 데이터와 class 포인터 존재)
- 존재 -> 처리, 존재X -> parent 참조를 따라 부모 클래스를 탐색
- 최상위 클래스인 Object 클래스까지 메서드를 탐색 후, 찾지 못한 경우에는 에러를 발생시키고 메서드 탐색을 종료
동적 메서드 탐색의 입장에서 상속 계층은 메시지를 수신한 객체가 자신이 이해할 수 없는 메시지를 부모 클래스에게 전달하기 위한 물리적인 경로를 정의하는 것이다.
public class GradeLecture extends Lecture {
@Override
public String getEvaludationMethod() {
return "Grade";
}
}
이런 복잡한 과정으로 인해 최악의 경우에는 실제로 실행될 메서드를 이해하기 위해 상속 계층 전체를 훑어가며 코드를 이해해야 하는 상황이 발생할 수 있다. => 극단적으로 이해하기 어려운 코드
cf. 동적 타입 언어의 경우 메시지에 대해 예외를 던지는 것 외에도 doesNotUnderstand, method_missing 메시지에 응답할 수 있는 메서드를 구현할 수 있다.
단순히 부모 클래스에 정의된 메서드를 실행하기 위한 것이 아니다.
'지금부터 이 클래스의 부모 클래스에서부터 메서드 탐색을 시작하라' 이다.
부모 클래스부터 시작해 Object 클래스의 메서드까지 탐색한다.
- 포워딩 : 다른 객체에게 요청을 처리할 때 self를 전달하지 않음
- 위임 : self 참조를 전달하는 경우
위임의 정확한 용도 : 클래스를 이용한 상속 관계를 객체 사이의 합성 관계로 대체해서 다형성을 구현하는 것