상속 (객체 지향 프로그래밍)

객체 지향 프로그래밍(OOP)에서, 상속(inheritance)은 객체들 간의 관계를 구축하는 방법이다. 클래스로 객체가 정의되는 고전 상속에서, 클래스는 기반 클래스, 슈퍼클래스, 또는 부모 클래스 등의 기존의 클래스로부터 속성과 동작을 상속받을 수 있다. 그 결과로 생기는 클래스를 파생 클래스, 서브클래스, 또는 자식 클래스라고 한다. 상속을 통한 클래스들의 관계는 계층을 형성한다. 프로토타입 기반 프로그래밍에서는, 객체가 클래스를 따로 정의할 필요 없이 다른 객체로부터 직접 정의될 수 있다. 이러한 특징을 차등 상속이라고 한다.

역사 편집

1966년 토니 호어는 공통의 속성을 지녔지만 다른 종류의 태그와 필드들로 구별되는 레코드 서브클래스를 제시했다. 이로부터 영향을 받은 올요한 달(Ole-Johan Dahl)과 크리스텐 나이가드(Kristen Nygaard)는, 서로 다른 클래스에 속하지만 공통의 속성을 가지는 객체를 허용하는 디자인을 제시했다. 이 디자인에서 공통의 속성들은 수퍼클래스를 구성했으며, 수퍼클래스들은 자기의 수퍼클래스 또한 가질 수 있었다. 이 아이디어는 1968년 시뮬라 67에 적용되었으며,[1] 이후 스몰토크, C++, 자바파이썬으로 퍼져나갔다.

서브클래스와 수퍼클래스 편집

"파생 클래스" 또는 후계자 클래스, 자식 클래스라고도 불리는 서브클래스는 하나 이상의 다른 클래스(수퍼클래스, 기반 클래스, 또는 부모 클래스)로부터 하나 이상의 언어 엔티티를 상속하는 모듈러, 파생 클래스이다. 클래스 상속의 의미는 언어에 따라 달라지지만, 일반적으로 서브클래스는 수퍼클래스의 인스턴스 변수들과 멤버 함수들을 자동적으로 상속한다. 어떤 언어들은 다른 구조의 상속을 지원하기도 한다. 예를 들어, 에펠에서 클래스의 사양을 정의하는 계약도 후계자가 상속받는다. 수퍼클래스는 특정한 서브클래스가 상속하고 수정, 보완할 수 있는 공통 인터페이스와 기본적인 기능을 수립한다. 서브클래스에 의해 상속된 소프트웨어는 서브클래스에서 재사용된다. 클래스의 인스턴스에 대한 참조는 사실 그것의 서브클래스 중 하나를 참조하는 것이다. 참조되는 객체의 실제 클래스를 컴파일 타임에 예측하는 것은 불가능하다. 수많은 다른 클래스의 객체 멤버 함수를 호출하는데에는 똑같은 인터페이스가 사용된다. 서브클래스는 수퍼클래스의 함수를 같은 메소드 시그니처를 공유해야 하는 완전히 새로운 함수로 대체할 수도 있다.

상속 불가 클래스 편집

일부 언어에서는 클래스 선언에 특정한 클래스 한정자를 추가함으로써 그 클래스가 상속 불가하다고 선언할 수 있다. 자바의 "final" 키워드 또는 C#의 "sealed" 키워드가 그 예이다. 이러한 한정자들은 클래스 선언에서 "class" 키워드와 클래스 식별자의 선언 전에 추가된다. 봉인(sealed) 클래스는 특히 개발자들이 소스 코드에 권한이 없고 미리 컴파일된 바이너리에만 권한이 있을 때, 재사용이 제한된다. 봉인 클래스에는 서브클래스가 없다. 그래서 클래스 객체의 참조 또는 포인터가 서브클래스의 인스턴스(존재하지 않음)나 수퍼클래스의 인스턴스(참조 타입을 업캐스팅하는 것은 타입 체계에 위반됨)가 아닌 해당 클래스의 인스턴스를 참조하고 있다는 것을 컴파일 타임에 쉽게 추론할 수 있다: 서브 타입 다형성. 실행 전에 참조되는 객체의 정확한 타입을 알 수 있기 때문에, 초기 바인딩(또는 "정적 디스패치")이 후기 바인딩 ("동적 디스패치" 또는 "동적 바인딩") 대신에 사용될 수 있다. 이것은 사용되고 있는 프로그래밍 언어에서 다중 상속이 지원되는지 또는 단일 상속만이 지원되는지에 따라서 한 회 이상의 가상 메소드 테이블 조회를 필요로 한다.

오버라이드 할 수 없는 메소드 편집

클래스가 봉인(sealed) 또는 최종화(finalized) 될 수 있는 것처럼 메소드 선언에서도 메소드가 오버라이드(즉, 서브클래스에서 같은 이름과 타입 시그니처를 가진 새로운 함수로 대체)되는 것을 막는 메소드 한정자를 가질 수 있다. 프라이빗 메소드는 순전히 그것이 멤버 함수인 클래스가 아닌 다른 클래스에서는 액세스 할 수 없기 때문에 오버라이드 할 수 없다. 자바의 "final" 메소드 또는 C#의 "sealed" 메소드도 오버라이드 할 수 없다.

가상 메소드 편집

수퍼클래스 메소드가 가상 메소드인 경우, 수퍼클래스의 메소드의 호출은 동적 디스패치된다. 일부 언어(예: C++)에서는 특정 메소드가 가상으로 선언되어야 하고, 기타 언어(예: 자바)에서는 모든 메소드가 가상이어야 한다. 비가상 메소드의 호출은 항상 정적으로 디스패치된다 (즉, 함수 호출의 주소는 컴파일 타임에 결정된다).정적 디스패치는 동적 디스패치보다 빠르고 인라인 확장과 같은 최적화를 가능하게 한다.

같이 보기 편집

각주 편집

  1. Mike Mintz, Robert Ekendahl (2006). 《Hardware Verification with C++: A Practitioner’s Handbook》. United States of America: Springer. 22쪽. ISBN 0-387-25543-5.