본문 바로가기
책/오브젝트

12. 다형성

by 오오오오니 2025. 3. 17.

12. 다형성

비어 있음
2024년 5월 14일
단순히 코드를 재사용하기 위해서라면 상속을 사용하지 말아야 한다.

다형성

여러 타입을 대상으로 동작할 수 있는 코드를 작성할 수 있는 방법

상속의 양면성

상속은 다형성을 가능하게 하는 타입 계층을 구축하기 위한 것이다.
데이터 관점의 상속
자식 클래스의 인스턴스는 자동으로 부모 클래스에서 정의한 모든 인스턴스 변수를 내부에 포함하게 되는 것
행동 관점의 상속
메시지를 수신한 객체는 자신의 클래스에 메서드가 존재하지 않으면 parent포인터를 따라 부모 클래스를 차례대로 훑어가면서 적절한 메서드가 존재하는지를 검색한다.

업캐스팅과 동적 바인딩

업캐스팅 : 부모 클래스 타입으로 선언된 변수에 자식 클래스의 인스턴스를 할당하는 것
동적 바인딩 : 선언된 변수의 타입이 아니라 메시지를 수신하는 객체의 타입에 따라 실행되는 메서드가 결정된다. 객체지향 시스템이 메시지를 처리할 적절한 메서드를 컴파일 시점이 아니라 실행 시점에 결정하기 때문에 가능하다.
💡
개방-폐쇄 원칙과 의존성 역전 원칙 개방-폐쇄 원칙은 유연하고 확장 가능한 코드를 만들기 위해 의존관계를 구조화 하는 방법을 설명한다. 업캐스팅과 동적 바인딩은 이 원칙에 이르는 방법이다.

동적 메서드 탐색과 다형성

다음 규칙에 따라 실행할 메서드를 선택한다.
메시지를 수신한 객체는 먼저 자신을 생성한 클래스에 적합한 메서드가 존재하는지 검사한다. 존재하면 메서드를 실행하고 탐색을 종료한다.
메서드를 찾지 못했다면 부모 클래스에서 메서드 탐색을 계속한다. 이 과정은 적합한 메서드를 찾을 때까지 상속 계층을 따라 올라가며 계속된다.
상속 계층의 가장 최상위 클래스에 이르렀지만 메서드를 발견하지 못한 경우 예외를 발생시키며 탐색을 중단한다.

자동적인 메시지 위임

상속을 이용할 경우 코드에 메시지 위임을 명시적으로 작성할 필요가 없다. 상속계층을 따라 자동으로 위임된다.
루비의 모듈, 스몰토그와 스칼라의 트레이트, 스위프트의 프로토콜과 확장
이름만 같고 시그니처가 완전히 동일하지 않은 메서드들은 상속 계층에 걸쳐 사이좋게 공존할 수도있다.
⇒ 메서드 오버로딩
: 시그니처가 다르기 때문에 동일한 이름의 메서드가 공존하는 경우를 메서드 오버로딩이라고 부른다.

self 대 super

self 참조는 메시지를 수신한 객체의 클래스에 따라 메서드 탐색을 위한 문맥을 실행 시점에 결정한다.
동적 바인딩과 self참조는 동일한 메시지를 수신하더라도 객체의 타입에 따라 적합한 메서드를 동적으로 선택할 수 있게 한다.

상속 대 위임

위임과 self참조

자신이 수신한 메시지를 다른 객체에게 동일하게 전달해서 처리를 요청하는 것을 위임이라고 부른다.
상속이 매력적인 이유는 우리가 직접 구현해야 하는 이런 번접한 과정을 자동으로 처리해 준다는 점이다.
self참조의 전달은 결과적으로 자식 클래스의 인스턴스와 부모 클래스의 인스턴스 사이에 동일한 실행 문맥을 공유할 수 있게 해준다.

느낀점

self참조를 직접구현하는 과정을 보니까 상속이 참 매력적으로 느껴졌다.
다형성에 대해 살펴볼 수 있어서 좋았고 언급된 다른 언어(루비의 모듈, 스몰토그와 스칼라의 트레이트, 스위프트의 프로토콜과 확장)에서 어떻게 다형성을 구현하는지 궁금해졌다.

' > 오브젝트' 카테고리의 다른 글

14. 일관성 있는 협력  (0) 2025.03.17
13. 서브클래싱과 서브타이핑  (0) 2025.03.17
11. 합성과 유연한 설계  (0) 2025.03.17
10. 상속과 코드 재사용  (0) 2025.03.17
09. 유연한 설계  (0) 2025.03.17