拡張関数と拡張プログラム


リファレンス
Kotlinアクションを表示して作成します.

拡張関数


拡張関数の概念


拡張関数は、クラスのメンバーメソッドのように呼び出すことができますが、クラスの外で宣言された関数です.
package strings

fun String.lastChar() : Char = this.get(this.length - 1)
展開関数を作成するには、追加する関数名の前に展開するクラスの名前を追加します.クラス名は受信オブジェクトタイプ(receiver type)と呼ばれ、拡張関数呼び出しのターゲット値(オブジェクト)は受信オブジェクト(receiver object)と呼ばれます.

受信オブジェクトタイプは、展開するクラスを定義するタイプで、受信オブジェクトはそのクラスに属するインスタンスオブジェクトです.
package strings

// 수신 객체 멤버에 this 없이 접근
fun String.lastChar() : Char = get(length - 1)
展開関数では、通常のインスタンスメソッドと同様に、受信オブジェクトのメソッドまたは構成を直接使用できます.従来の方法の本明細書でthisを使用する場合と同様に、拡張関数の本文でthisを使用することもできます.拡張関数は、従来の方法と同様に、本明細書では省略することもできます.
ただし、拡張関数はパッケージを破壊しません.クラスで定義する方法とは異なり、拡張関数のプライベートメンバーまたは保護されたメンバーは使用できません.クラスでのみ使用できます.

関数のインポートと拡張


拡張関数を使用するには、他のクラスや関数をインポートするように、関数をインポートする必要があります.
コトリンでは、インポートクラスと同じ構文を使用して単一の関数をインポートするか、*(Starimport)を使用してインポートできます.
import strings.lastChar
또는
import strings.*

val c = "kotlin".lastChar()
asキーを使用すると、インポートしたクラスまたは関数を異なる名前で呼び出すこともできます.
import strings.lastChar as last

val c = "kotlin".last()

Javaから拡張関数を呼び出す


内部展開関数は静的メソッドであり,オブジェクトを最初のパラメータとして受信する.したがって、拡張関数を呼び出すと、他のアダプタオブジェクトやランタイムポイントのコストは増加しません.
したがって、Javaで拡張関数を呼び出すには、静的メソッドを呼び出し、受信オブジェクトを最初のパラメータとして使用します.他の上位関数と同様に、拡張関数を含むJavaクラス名も拡張関数を含むファイル名によって決定されます.
// lastChar 확장 함수가 정의된 코틀린 파일의 이름을 StringUtil.kt라고 가정
char c = StringUtilkt.lastChar("Java");

拡張関数は上書きできません


従来のオブジェクト向けメソッドのオーバーライドと同様に、ネストメソッドのオーバーライドは拡張関数をオーバーライドできません.
拡張関数は、クラスの一部ではなくクラスの外に宣言されます.親クラスと子クラスで同じ名前とパラメータを持つ拡張関数を定義すると、実際に拡張関数を呼び出すときに受信オブジェクトの変数として指定される静的タイプ(コンパイル時)は、その変数に格納されているオブジェクトの動的タイプ(実行時)を決定せずに、どの拡張関数を呼び出すかを決定します.
open class View {}

// Button 클래스가 View 클래스 상속
class Button : View() {}

// 확장 함수 정의
fun View.showOff() = println("view")
fun Button.showOff() = println("Button")

fun main() {
    // View 타입 변수에 자식인 Button 객체 대입
    val view: View = Button()
    // 만약 일반적인 override였다면 동적으로 결정되어 Button의 메서드가 실행되었겠지만
    // 확장함수는 정적으로 결정되므로 View클래스의 메서드가 실행
    view.showOff()
}
ビューが指すオブジェクトの実際のタイプはButtonですが、この場合、ビューのタイプがViewであるため、ビューの拡張関数は無条件に呼び出されます.
拡張関数を静的javaメソッド(最初のパラメータは受信オブジェクト)にコンパイルすることを覚えている場合は、この動作は簡単に理解できます.
View view = new Button();
// 위의 kotlin 파일이 Extensions.kt라고 가정
ExtensionsKt.showOff(view);

拡張プロトコル


拡張プロファイルを使用すると、既存のクラスオブジェクトのプロファイル形式として使用できる構文のAPIを追加できます.ただし、拡張構成には実際にはステータスはありません.これは「構成」と呼ばれますが、ステータスは保存できません(既存のクラスのインスタンスオブジェクトにフィールドを追加できません).
拡張関数と同様に、拡張プロパティも従来のプロパティと同様に、受信オブジェクトクラスが追加されただけです.サポートされているフィールド(フィールド)がないため、基本的なラスタ実装は提供されないため、少なくとも1つのラスタを定義する必要があります.同様に、初期化コードに計算された値を格納できる場所がないため、初期化コードを書き込むことはできません.
val String.lastChar: Char
    get() = get(length - 1)