1. 序章

このチュートリアルでは、Kotlinプロパティとそれらにアクセスする方法を見ていきます。 プロパティはJavaのフィールドに似ていますが、いくつかの重要な違いがあります。

たとえば、プロパティには自動生成されたゲッターとセッターがあります。 また、最上位のパッケージスコープで宣言することもできます。クラスに属している必要はありません。

2. プロパティのゲッターとセッター

Kotlinでは、プロパティは明示的なゲッターまたはセッターメソッドを必要としません

var author: String = "Frank Herbert"

これは、次の get()および set()メソッドを定義するのと同じです。

var author: String = "Frank Herbert"
    get() {
        return field
    }
    set(value) {
        field = value
    }

デフォルトのゲッターとセッターは、Javaで見られるおなじみのパターンですが、Kotlinでは、プロパティのプライベートバッキングフィールドを作成する必要はありません。

ドット構文を使用して、クラスプロパティのゲッターとセッターを呼び出すことができます。

val book = Book()
print(book.author) // prints "Frank Herbert"
book.author = "Kurt Vonnegut"
print(book.author) // prints "Kurt Vonnegut"

プロパティの基本的な機能を理解したので、プロパティを変更するいくつかの方法を見てみましょう。

2.1. バッキングフィールドへのアクセス

私たちが定義するすべてのプロパティは、特別なfieldキーワードを使用してget()およびset()メソッド内でのみアクセスできるフィールドによって支えられています。 field キーワードは、またはにアクセスするために使用されますプロパティの値を変更します。 これにより、 get()および set()メソッド内でカスタムロジックを定義できます。

var rating: Int = 5
    get() {
        if (field < 5) {
            print("Warning: this is a terrible book")
        }
        return field
    }
    set(value) {
        field = when {
            value > 10 -> 10
            value < 0 -> 0
            else -> value
        }
    }

カスタムゲッターまたはセッターを定義すると、入力検証、ロギング、データ変換などの便利な操作をいくつでも実行できます。 このビジネスロジックをゲッターまたはセッターに直接追加することで、プロパティにアクセスしたときに常に実行されるようにします。

getterメソッドとsetterメソッドの副作用をできるだけ回避または最小限に抑えるようにしてください。 コードが理解しにくくなります。

2.2. val対。 var

プロパティの値を変更できるようにする場合は、varキーワードでマークを付けます。 不変のプロパティが必要な場合は、valキーワードでマークします。 主な違いは val プロパティにセッターを含めることはできません。

カスタムゲッターを定義すると、valプロパティが実際にその値を変更する可能性があります。 たとえば、 isWorthReading プロパティは、可変のratingプロパティを使用してその値を計算します。

val isWorthReading get() = this.rating > 5

この意味で、プロパティはカスタムゲッターを使用するときのメソッドとして機能します。 プロパティを計算するために高価または低速の操作を行う必要がある場合は、明確にするためのメソッドを使用する方がよいでしょう。プロパティを使用するとき、開発者は、メモリから値を取得するだけではないことに気付かない場合があります。 。

2.3. 可視性修飾子

Javaでは、クラスフィールドにパブリック読み取りアクセスとプライベート書き込みアクセスを持たせたいことがよくあります。 publicgetterメソッドとprivateまたはprotected setterメソッドを使用すると、これを実現できます。 Kotlinは、プロパティの set()メソッドで可視性修飾子を許可することにより、このアクセスパターンを実装する簡潔な方法を提供します。

var inventory: Int = 0
    private set

これで、bookクラスのすべてのコンシューマーが Inventory プロパティを読み取ることができますが、変更できるのはBookクラスのみです。 プロパティのデフォルトの可視性はパブリックであることに注意してください。

ゲッターは常にプロパティ自体と同じ可視性を持ちます。 たとえば、プロパティが private の場合、ゲッターはプライベートです。

3. Javaの相互運用性

KotlinからJavaコードを呼び出す場合、ゲッターとセッターに適切な名前が付けられていれば、コンパイラーはJavaフィールドをプロパティに自動的に変換します。 Javaクラスに、「get」で始まる引数なしメソッドによってアクセスされ、「set」で始まる単一引数メソッドで変更されたフィールドがある場合、Kotlinのvarプロパティになります。

たとえば、Javaのロギングライブラリの LoggerクラスのgetLevel()および setLevel()メソッドは次のとおりです。

val logger = Logger.getGlobal()
logger.level = Level.SEVERE 
print(logger.level) // prints "SEVERE"

フィールドにパブリックゲッターのみがあり、パブリックセッターがない場合、Kotlinのvalプロパティになります。たとえば、Loggerクラスのnameフィールドは次のようになります。

print(logger.name) // prints "global"
logger.name = "newName" // causes a compiler error

4. 結論

このチュートリアルでは、プロパティのゲッターとセッターを調べました。 オプションのget()および set()メソッドを通じて、強力で簡潔な機能を提供します。 これらのメソッドで高価な計算を実行しないように注意し、コードをクリーンで理解しやすい状態に保つために副作用を最小限に抑える必要があります。

このチュートリアルで使用されているコード例は、GitHubから入手できます。