본 글은 https://kotlinlang.org/docs/home.html 를 기반으로 작성자 마음대로 번역한 글입니다.
오역 & 의역이 빈번하며 모든 질문 및 태클 환영합니다!
2022-04-07 기준으로 작성되었습니다.
코틀린은 클래스를 상속하거나 Decorator와 같은 디자인 패턴을 사용하지 않고 기능적으로 새롭게 클래스를 확장하는 기능을 제공합니다. 이것은 extensions라는 특별한 선언을 통해 이루어집니다.
예를 들어, 수정할 수 없는 써드파티 라이브러리의 클래스에 새로운 함수를 작성할 수 있습니다. 이러한 함수들은 본래 함수의 메소드였더라도 일반적인 방식을 통해 호출할 수 있습니다. 이러한 기능은 extension function이라고 불립니다. 존재하는 클래스에 새로운 프로퍼티를 정의할 수 있는 extension properties 또한 존재합니다.
Extension functions
확장 함수를 선언하기 위해서, 이름 앞에 확장되는 타입을 참조하는 receiver type을 이름 앞에 붙여야 합니다. 다음은 MutableLive<Int>에 swap 함수를 추가한 것입니다.
확장 함수 내부의 this 키워드는 수신 객체(점 앞에 전달된 객체)에 해당합니다. 이제, 모든 MutableList<Int>에 대해 함수를 호출할 수 있습니다.
이 함수는 모든 MutableList<T>에 대해 제네릭으로 사용할 수 있습니다.
수신 타입 표현식에서 사용하기 위해서는 함수의 이름 전에 제네릭 타입 파라미터를 선언해야합니다.
Extensions are resolved statically
확장 함수는 확장하는 클래스를 실질적으로 수정하지 않습니다. 확장 함수를 정의함으로써, 클래스에 새로운 멤버를 삽입하는 것이 아니라, 해당 타입의 변수의 점표기로민 새로운 함수를 호출 가능하게 만듭니다.
확장 함수는 수신 타입에 따라 가상이 아닌 statically하게 디스패치됩니다. 호출되는 확장 함수는 런타임에 표현식을 계산한 결과의 타입이 아닌, 함수가 호출되는 표현식의 타입에 따라 결정됩니다.
이 예시는 확장 함수가 Shape 클래스인 파라미터 s의 타입에만 의존하기 때문에 Shape를 출력합니다.
클래스가 확장 함수와 동일한 수신 타입과, 같은 이름을 가지며 주어진 인수에 적용할 수 있는 멤버 함수를 가진 경우, 멤버 항수가 항상 우선입니다.
이 코드는 Class method를 출력합니다.
같은 이름을 가지지만 다른 시그니쳐를 가져 멤버 함수를 오버로드한 확장 함수는 문제 없습니다.
Nullable receiver
확장 함수는 nullable 수신 타입으로 정의될 수 있습니다. 이러한 확장 함수들은 객체 변수가 null이더라도 호출될 수 있으며, 내부에서 this == null로 확인할 수 있습니다.
이러한 방식으로, 확장 함수 내에서 검사를 수행하므로 코틀린에서는 null을 확인하지 않고 toString()을 호출할 수 있습니다.
Extension properties
코틀린은 함수를 지원하는 것처럼 확장 프로퍼티를 지원합니다.
확장 기능은 실제로 멤버를 클래스에 삽입하지 않으므로, 확장 프로퍼티에는 backing field↗가 부여되지 않습니다. 이것이 확장 프로퍼티에 대해 초기화가 허용되지 않는 이유입니다. 이러한 동작은 getter/setter를 명시적으로 제공함으로써만 정의될 수 있습니다.
예시 :
Companion object extensions
클래스에 companion object↗가 선언되어 있다면, companion object에 대한 확장 함수와 프로퍼티를 정의할 수 있습니다. companion object의 일반적인 멤버처럼 식별자로 클래스의 이름을 사용하여 호출할 수 있습니다.
Scope of extensions
대부분의 경우에서, 확장 기능을 패키지 바로 아래의 최상위 수준에서 정의합니다.
Declaring extensions as members
한 클래스에 대한 확장 기능을 다른 클래스에서 선언할 수 있습니다. 이러한 일부 확장에는 식별자 없이 멤버에 접근할 수 있는 객체인 여러 implicit receivers가 있습니다. 확장이 선언된 클래스의 인스턴스를 dispatch receiver라고 하며, 확장 메소드 수신 타입의 인스턴스를 extension receiver라고 합니다.
dispatch receiver와 extension receiver의 멤버 사이의 이름 충돌에서는, extension receiver가 우선 순위를 갖습니다. dispatch receiver의 멤버를 우선으로 하기 위해서, qualified this syntax↗를 사용할 수 있습니다.
멤버로 선언된 확장 기능은 open으로 선언되어 서브 클래스에서 상속될 수 있습니다. 이러한 함수의 dispatch는 dispatch receiver type에 대해 가상적이지만, extension receiver type에 대해서는 정적입니다.
Note on visibility
확장은 동일한 범위에서 선언된 일반 함수와 동일한 visibility modifiers↗를 사용합니다.
- 파일의 최상위에서 선언된 확장 기능은 같은 파일의 private 최상위 선언에 접근할 수 있습니다.
- 확장 기능이 receiver type 외부에서 선언되었다면, receiver의 private이나 protected 멤버에는 접근할 수 없습니다.
https://kotlinlang.org/docs/extensions.html
Extensions | Kotlin
kotlinlang.org
'Kotlin > Docs' 카테고리의 다른 글
[Kotlin Docs] Sealed classes (0) | 2022.04.08 |
---|---|
[Kotlin Docs] Data classes (0) | 2022.04.07 |
[Kotlin Docs] Visibility modifiers (0) | 2022.02.24 |
[Kotlin Docs] Functional (SAM) interfaces (0) | 2022.02.17 |
[Kotlin Docs] Interfaces (0) | 2022.02.04 |