오브젝트 Ch.12

Manx·2022년 5월 25일
0
post-thumbnail

'오브젝트: 코드로 이해하는 객체지향 설계' 3~4주차
분량 : Ch.11 ~ Ch.15
기간 : 22.5.21 ~ 22.6.4

Ch.12 다형성

다형성(Polymorphism)
그리스어에서 '많은'을 의미하는 'poly' + '형태'를 의미하는 'morph'의 합성어로 많은 형태를 가질 수 있는 능력을 의미한다.
=> 여러 타입을 대상으로 동작할 수 있는 코드를 작성할 수 있는 방법

  • 다형성의 분류
    • 유니버설
      • 매개변수
      • 포함
    • 임시
      • 오버로딩
      • 강제

매개변수 다형성

=> 메서드 오버로딩을 사용해 동일한 메서드 이름을 다양하게 사용할 수 있는 것

강제 다형성

=> 강제 형변환을 통해 동작

매개변수 다형성

제네릭 프로그래밍과 관련이 높음
예를 들어, List 인터페이스는 보관할 요소의 타입을 임의의 타입 T로 지정해 인스턴스를 생성하는 시점에 T를 구체적인 타입으로 지정할 수 있게 한다.

포함 다형성 (서브타입 다형성)

메시지가 동일하더라도 수신한 객체의 타입에 따라 실제로 수행되는 행동이 달라지는 능력
일반적으로 다형성은 포함 다형성을 의미한다.

// DiscountPolicy를 구현하는 다른 인스턴스로 조합 가능
public class Movie {
	private DiscountPolicy discountPolicy;
}

상속의 진정한 목적은 코드 재사용이 아니라 다형성을 위한 서브타입 계층을 구축하는 것이다.


동적 메서드 탐색과 다형성

실행할 메서드를 선택하는 방법

  • 메시지를 수신한 객체는 먼저 자신을 생성한 클래스에 적합한 메서드가 존재하는지 검사한다. 존재하면 메서드를 실행하고 탐색을 종료한다.
  • 메서드를 찾지 못했다면 부모 클래스에서 메서드 탐색을 계속한다. 이 과정은 적합한 메서드를 찾을 때까지 상속 계층을 따라 올라가며 계속된다.
  • 상속계층의 가장 최상위 클래스에 이르렀지만 메서드를 발견하지 못한 경우 예외를 발생시키며 탐색을 중단한다.
  1. self 참조가 가리키는 메모리로 이동한다. (객체의 현재 상태를 표현하는 데이터와 class 포인터 존재)
  2. 존재 -> 처리, 존재X -> parent 참조를 따라 부모 클래스를 탐색
  3. 최상위 클래스인 Object 클래스까지 메서드를 탐색 후, 찾지 못한 경우에는 에러를 발생시키고 메서드 탐색을 종료

자동적인 메시지 위임

동적 메서드 탐색의 입장에서 상속 계층은 메시지를 수신한 객체가 자신이 이해할 수 없는 메시지를 부모 클래스에게 전달하기 위한 물리적인 경로를 정의하는 것이다.

동적인 문맥

public class GradeLecture extends Lecture {
	@Override
    public String getEvaludationMethod() {
    	return "Grade";
    }
}
  1. GradeLecture에 stats 메시지를 전송
  2. self 참조는 GradeLecture부터 시작해 부모 클래스인 Lecture에서 메서드를 발견해 실행
  3. Lecture 클래스의 stats 메서드를 실행하는 중에 self 참조가 가리키는 객체에게 getEvaluationMethod 메시지를 전송
  4. 메서드 탐색은 self 참조가 가리키는 객체(GradeLecture)에서 시작한다.
  5. 따라서 메시지 탐색은 Lecture 클래스를 벗어나 self 참조가 가리키는 GradeLecture에서부터 다시 시작된다.

    이런 복잡한 과정으로 인해 최악의 경우에는 실제로 실행될 메서드를 이해하기 위해 상속 계층 전체를 훑어가며 코드를 이해해야 하는 상황이 발생할 수 있다. => 극단적으로 이해하기 어려운 코드


cf.
동적 타입 언어의 경우 메시지에 대해 예외를 던지는 것 외에도 doesNotUnderstand, method_missing 메시지에 응답할 수 있는 메서드를 구현할 수 있다.

super의 의미

단순히 부모 클래스에 정의된 메서드를 실행하기 위한 것이 아니다.
'지금부터 이 클래스의 부모 클래스에서부터 메서드 탐색을 시작하라' 이다.
부모 클래스부터 시작해 Object 클래스의 메서드까지 탐색한다.

포워딩과 위임

  • 포워딩 : 다른 객체에게 요청을 처리할 때 self를 전달하지 않음
  • 위임 : self 참조를 전달하는 경우

위임의 정확한 용도 : 클래스를 이용한 상속 관계를 객체 사이의 합성 관계로 대체해서 다형성을 구현하는 것

profile
백엔드 개발자

0개의 댓글