본문 바로가기

책/Object

다형성

다형성(Polymorphism)

하나의 추상 인터페이스에 대해 코드를 작성하고 이 추상 인터페이스에 대해 서로 다른 구현을 연결할 수 있는 능력

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

 유니버셜(Universal) 다형성

 매개변수(Parametric) 다형성

  클래스의 인스턴스 변수나 메서드의 매개변수 타입을 임의의 타입으로 선언한 후 사용하는 시점에 구체적인 타입으로 지정하는 방식

 제네릭 프로그래밍과 관련이 높음

 포함(Include) 다형성

 메시지가 동일하더라도 수신한 객체의 타입에 따라 실제로 수행되는 행동이 달라지는 방식

 객체지향 프로그래밍에서 가장 널리 알려진 형태의 다형성

 상속을 사용 : 어떤 메시지, 어떤 클래스의 인스턴스인지에 따라 처리할 적절한 메서드를 상속 계층 안에서 탐색

 서브타입(Subtype) 다형성이라고도 부름 : 자식 클래스가 부모 클래스의 서브타입이어야 함

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

 임시(Ad Hoc) 다형성

 오버로딩(Overloading) 다형성

 하나의 클래스 안에 동일한 이름의 메서드가 존재

 유사한 작업을 수행하는 메서드의 이름을 통일

 강제(Coercion) 다형성

 언어가 지원하는 자동적인 타입 변환이나 사용자가 직접 구현한 타입 변환을 이용해 동일한 연산자를 다양한 타입에 사용할 수 있는 방식

 오버로딩 다형성과 강제 다형성을 함께 사용하면 모호해질 수 있음

  - 실제로 어떤 메서드가 호출될지 판단하기가 어려워짐

상속의 양면성

데이터 관점의 상속 : 부모 클래스에서 정의한 모든 데이터를 자식 클래스의 인스턴스에 포함시킴

행동 관점의 상속 : 데이터뿐만 아니라 부모 클래스에서 정의한 일부 메서드를 자식 클래스에 포함시킴

상속의 목적은 코드 재사용이 아니고, 프로그램을 구성하는 개념들을 기반으로 다형성을 가능하게 하는 타입 계층을 구축하는 것

메서드 오버라이딩 : 부모 클래스의 구현을 자식 클래스에서 새로운 구현으로 대체(자식 클래스의 우선순위가 높음)

메서드 오버로딩 : 부모 클래스에서 정의한 메서드와 이름은 동일하지만 시그니처는 다른 메서드를 자식 클래스에 추가


업캐스팅과 동적 바인딩

업캐스팅 : 부모 클래스 타입으로 선언된 변수에 자식 클래스의 인스턴스를 할당하는 것

다운 캐스팅 : 부모 클래스의 인스턴스를 자식 클래스 타입으로 변환

동적 바인딩(지연 바인딩) : 선언된 변수의 타입이 아니라 메시지를 수신하는 객체의 타입에 따라 실행되는 메서드가 결정(메시지를 처리할 메서드를 런타임에 결정)

정적 바인딩(초기 바인딩, 컴파일 타임 바인딩) : 코드를 작성하는 시점(컴파일타임)에 호출될 메서드가 결정


동적 메서드 탐색과 다형성

객체지향 시스템은 다음 규칙에 따라 실행할 메서드를 선택

1. 메시지를 수신한 객체는 먼저 자신을 생성한 클래스에 적합한 메서드가 존재하는지 검사 -> 존재하면 메서드를 실행하고 탐색을 종료

2. 부모 클래스에서 메서드 탐색 -> 상속 계층을 따라 올라가며 계속됨

3. 상속 계층의 최상위 클래스까지 메서드를 발견하지 못한 경우 -> 예외를 발생시키며 탐색 중단

self 참조

 - 객체가 메시지를 수신하면 self 참조라는 임시 변수를 자동으로 생성한 후 메시지를 수신한 객체를 가리키도록 설정

 - 동적 메서드 탐색은 self가 가리키는 객체의 클래스에서 시작해서 상속 계층의 역방향으로 이뤄지며 메서드 탐색이 종료되는 순간 소멸됨

동적 메서드 탐색

1. 자동적인 메시지 위임 : 자식 클래스는 자신이 이해할 수 없는 메시지를 전송받은 경우 상속 계층을 따라 부모 클래스에게 처리를 위임

2. 동적인 문맥 사용 : 메시지를 수신했을 때 실제로 어떤 메서드를 실행할지를 결정하는 것은 컴파일 시점이 아닌 실행 시점에 이루어짐 -> self 참조 사용


상속 대 위임

상속은 동적으로 메서드를 탐색하기 위해 현재의 실행 문맥을 가지고 있는 self 참조를 전달

 - 객체들 사이에서 메시지를 전달하는 과정은 자동으로 이루어짐(자동적인 메시지 위임)

위임(delegation)

 - 자신이 수신한 메시지를 다른 객체에게 동일하게 전달해서 처리를 요청하는 것

 - 항상 현재의 실행 문맥을 가리키는 self 참조를 인자로 전달

포워딩(forwarding)

 - self 참조를 전달하지 않고 메시지를 전송

프로토타입(prototype) 기반의 객체지향 언어에서 상속을 구현하는 유일한 방법은 객체 사이의 위임을 이용하는 것이다


' > Object' 카테고리의 다른 글

일관성 있는 협력  (0) 2020.09.01
서브클래싱과 서브타이핑  (0) 2020.08.25
합성과 유연한 설계  (0) 2020.07.27
상속과 코드 재사용  (0) 2020.07.27
유연한 설계  (0) 2020.07.13