코틀린 언어 정리 2-12
class 확장(Extensions)
코틀린에서는 클래스 내부에 멤버(함수나 프로퍼티)를 직접 선언하는 기본적인 방식 이외에 클래스 외부에서 멤버를 선언하는 방법이 있습니다. 좀 더 구체적으로 보면, 클래스 외부(전역, 지역 또는 다른 클래스 내부)에도 멤버와 비슷한 것을 선언할 수 있습니다. 코틀린에서는 이렇게 선언하는 것을 확장 이라고 합니다. 하지만 확장은 내부적 또는 외부적으로 일반 멤버와 완전히 동일하게 처리되는 것은 아닙니다. 확장은 실제로 클래스에 멤버를 추가하는 것이 아니고 단지 클래스 이름과 함수 또는 프로퍼티를 "."(dot)로 연결해 주는 문법을 지원하는 기법입니다.
특징(제한) 및 사례 분석
확장은 정적으로 동작합니다. 먼저 이해를 위해 상황을 가정해 보겠습니다. 먼저 A:B(클래스 A가 클래스 B를 상속 받음)와 같은 관계의 클래스들이 있다고 가정합니다. 확장으로 A와 B클래스에 동일한 선언(이름과 형식이 모두 같은)의 프로퍼티나 함수를 추가합니다.
이제 A type으로 생성한 a객체 B type으로 캐스팅하여 b 변수에서 참조합니다. 결과를 확인해 보겠습니다. b를 통해 확장함수나 프로퍼티 접근 시, 실제 생성된 객체의 타입은 A 이지만 이 객체를 참조하는 b 변수가 B type이기 때문에 B의 멤버가 선택됩니다. 즉 확장 함수는 실제 인스턴스에 맞는 함수가 호출되는, 다형성(가상함수)이 적용되지 않습니다.
여기까지만 보면 객체지향 개념에 익숙한 사람에게, 기존 객체지향 규칙이나 시스템에 확장이라는 개념이 하나 추가되어도 특별히 고려할 문제들은 없을 것 같습니다. 그냥 정적으로 동작하는 멤버로 간단하게 생각할 수 있습니다. 그런데 막상 사용하려고 하면 많은 새로운 예외적인 상황들이 발생합니다. 확장 선언 위치가 일반적인 멤버와 다르기 때문에 이에 따라 확장 접근 권한, 접근 우선 순위( 이름 충돌 상황 시 멤버 선택 등 )와 같은 새로운 상황들이 발생합니다. 이제부터 이런 사항들에 대해 케이스별로 예제를 이용해 확인해 보겠습니다.
확장과 멤버 접근 기본적인 우선순위 규칙
설명을 위해 이름 충돌 상황을 가정하여 우선순위를 케이스 별로 확인합니다.
구현 상황 가정
A:B 의 클래스 관계(A는 B를 상속받는 클래스)가 있다고 가정합니다.
함수나 프로퍼티 처리 방법은 동일하므로 이 후 설명은 함수 위주로 설명합니다.
클래스의 멤버 함수와 확장 함수 선언이 동일한 경우
멤버 함수만 접근 가능합니다.
예제
상위 클래스의 멤버 함수와 하위 클래스의 확장 함수 선언이 동일한 경우
상위 클래스의 멤버 함수만 접근 가능합니다.
예제
상위 클래스의 확장 함수와 하위 클래스의 확장 함수 선언이 동일한 경우
실제 생성된 객체의 타입과 상관 없이 객체 변수의 타입에 따라 확장 함수를 선택합니다. 즉 다형성에 의해 함수를 선택하지 않고 정적으로 선택합니다.
예제
우선순위 요약
멤버는 확장보다 항상 우선합니다. 상속 계층에서도 멤버와 확장 선언이 동일하면(겹치면, 충돌하면) 확장은 무시됩니다.
확장에는 다형성이 적용되지 않습니다.
'코틀린( Kotlin )' 카테고리의 다른 글
코틀린 2-14 class 확장(Extensions)-3 Nullable Receiver (0) | 2020.04.08 |
---|---|
코틀린 2-13 class 확장(Extensions)-2 확장 함수/프로퍼티 제약 (0) | 2020.04.08 |
코틀린 2-11 Object Expressions and Declarations (0) | 2020.04.07 |
코틀린 2-10 Anonymous inner class( object expression ) (0) | 2020.04.07 |
코틀린 2-9 Nested / Inner class (0) | 2020.04.06 |