오브젝트 - 12 다형성

yshjft·2023년 6월 21일
0

오브젝트

목록 보기
12/18
  • 상속의 목적은 코드 재사용이 아니다. 상속은 타입 계층을 구조화하기 위해 사용한다.
    • 단순히 코드를 재사용하기 위함이라면 상속을 사용해서는 안된다.
  • 다형성이 런타임에 메시지를 처리하기에 적합한 메서드를 동적으로 탐색하는 과정으로 통해 구현된다.
    • 상속은 이런 메서드를 찾기 위해 일종의 탐색 경로를 클래스 계층의 형태로 구현하기 위한 방법

01 다형성

  • 다형성
    • 여러 타입을 대상으로 동작할 수 있는 코드를 작성할 수 있는 방법
  • 오버로딩 다형성
    • 클래스 안에 동일한 이름의 메서드가 존재하는 경우
  • 강제 다형성
    • 자동적인 타입 변환이나 직접 구현한 타입 변환을 이용해 동일한 연산자를 다양한 타입에 사용할 수 있는 방식
  • 매개변수 다형성
    • 매개변수의 타입을 임의의 타입으로 선언한 후 사용하는 시점에 구체적인 타입으로 지정하는 방식
  • 포함 다형성(서브타입 다형성)
    • 메시지가 동일하더라도 수신한 객체의 타입에 따라 실제로 수행되는 행동일 달라지는 능력
    • 가장 널리 알려진 형태의 다형성
  • 상속의 진정한 목적은 코드 재사용이 아니라 다형성을 위한 서브타입 계층을 구축하는 것이다.

02 상속의 양면성

  • 상속은 다형성을 가능하게 하는 타입 계층을 구축하기 위한 것

상속을 사용한 강의 평가

데이터 관점의 상속

자식 클래스의 인스턴스는 자동으로 부모 클래스에서 정의한 모든 인스턴스 변수를 내부에 포함한다.

행동 관점의 상속

부모 클래스가 정의한 일부 메서드를 자식 클래스의 메서드로 포함시키는 것

03 업캐스팅과 동적 바인딩

같은 메시지, 다른 메서드

  • 업캐스팅
    • 부모 타입에 자식 클래스 인스턴스 할당
  • 동적 바인딩
    • 메시지를 수신하는 객체의 타입에 따라 실행되는 메서드가 결정된다.

업캐스팅

  • 다운캐스팅
    • 부모 클래스의 인스턴스를 자식 클래스 타입으로 변환하기 위한 명시적인 타입 캐스팅

동적 바인딩

  • 정적 바인딩, 초기 바인딩, 컴파일 타임 바인딩
    컴파일 타미에 호출할 함수를 결정하는 방식
  • 동적 바인딩, 지연 바인딩
    메시지를 수신했을 때 실행될 메서드가 런타임에 결정된다.

04 동적 메서드 탐색과 다형성

  • 객체지향 시스템은 아래 규칙에 따라 실행할 메서드를 선택한다.
    • 자신을 생성한 클래스에 적합한 메서드가 존재하는지 검사한다.
    • 부모 클래스에서 메서드 탐색을 계속
    • 메서드를 발견하지 못한 경우 예외를 발생시킨다
  • self 참조(this)
    • 객체가 메시지를 수신하면 컴파일러는 self 참조라는 임시 변수를 자동으로 생성한 후 메시지를 수신한 객체를 가리키도록 설정
    • 메서드 탐색이 종료되는 순간 self 참조는 자동으로 소멸
  • 자식 클래스의 메서드가 부모 클래스의 메서드보다 먼저 탐색
  • 메서드 탐색의 원리
    • 자동적인 메시지 위임
      자신이 이해할 수 없는 메시지를 전송받은 경우 상속계층을 따라 부모 클래스에게 처리를 위임한다.
    • 동적인 문맥 사용
      실행 시점에 어떤 메서드를 실행할지 결정

자동적인 메시지 위임

메서드 오버라이딩

메서드 오버로딩

동적인 문맥

  • 동일한 코드라고 하더라도 self 참조가 가리키는 객체가 무엇인지에 따라 메서드 탐색을 위한 상속 계층의 범위가 동적으로 변한다.
  • self 전송이 깊은 상속 계층과 계층 중간중간에 함정처럼 숨겨져 있는 메서드 오버라이딩과 만나면 극단적으로 이해하기 어려운 코드가 만들어진다.

이해할 수 없는 메시지

정적 타입 언어와 이해할 수 없는 메시지

  • 상속 계층 탐색을 컴파일 타임에 진행한다.

동적 타입 언어와 이해할 수 없는 메시지

  • 정적 타입 언어와 동일하게 상속 계층을 탐색한다.
  • 단, 컴파일 단계가 존재하지 않기 때문에 코드를 실행해보기 전에는 메시지 처리 가능 여부를 판단할 수 없다.
  • 객체지향의 이상에는 동적 타입 언어가 좀 더 가깝다. 다만 코드를 어렵고 복잡하게 만든다.
  • 정적 타입 언어는 유연성은 부족하지만 안정적인 코드를 만들 수 있다.

self 대 super

  • super 참조를 이용해 '메시지를 전송'한다...
    • super 참조를 통해 호출되는 메서드는 부모 클래스의 메서드가 아니라 더 상위에 위치한 조상 클래스의 메서드일 수 있기 때문이다.
    • super 참조의 정확한 의도는 '지금 이 클래스의 부모 클래스에서부터 메서드 탐색을 시작하세요'이다.
  • self는 메시지 탐색을 시작하는 클래스가 미정이지만 super는 미리 정해져 있다.

05 상속 대 위임

위임과 self 참조

  • 위임
    • 자신이 수신한 메시지를 다른 객체에게 동일하게 전달해서 처리를 요청하는 것
    • 자신이 정의하지 않거나 처리할 수 없는 속성 또는 메서드의 탐색 과정을 다른 객체로 이도시키기 위해 사용하는 것
    • 항상 self 참조를 인자로 전달한다.
  • 포워딩
    • 객체가 다른 객체로 요청을 처리할 때 인자로 self를 전달하지 않는 것

프로토타입 기반의 객체지향 언어!

  • js 프로토타입 관련 내용은 아래 이미지로 대체합니다.




profile
꾸준히 나아가자 🐢

0개의 댓글