0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Kotlin KoansでKotlin入門 第33回:Properties

Posted at

はじめに

公式の問題集「Kotlin Koans」を解きながらKotlinを学習します。

過去記事はこちら

問題

Properties

Propertiesについて学びます。
PropertyWithCounterが割り当てられるたびにカウンタ・プロパティがインクリメントされるように、PropertyExample.propertyWithCounterにカスタム・セッターを追加してください。

修正前コード.kt
class PropertyExample() {
    var counter = 0
    var propertyWithCounter: Int? = null
        set
}

問題のポイント

Kotlinのクラスのプロパティは、varキーワードでmutableとして、またはvalキーワードでread-onlyとして宣言することができます。プロパティを使用するには、単にその名前で参照します。

fun copyAddress(address: Address): Address {
    val result = Address() // there's no 'new' keyword in Kotlin
    result.name = address.name // accessors are called
    result.street = address.street
    // ...
    return result
}

プロパティに対してカスタムアクセサを定義することができます。カスタムゲッターを定義すると、そのプロパティにアクセスするたびに呼び出されます(この方法で、コンピューテッドプロパティを実装することができます)。
以下は、カスタムゲッターの例です。

class Rectangle(val width: Int, val height: Int) {
    val area: Int // ゲッターの戻り値の型から推測できるので、プロパティの型は任意
        get() = this.width * this.height
}
// Width=3, height=4, area=12

カスタム・セッターを定義すると、プロパティに値を代入するたびに、初期化を除いて、そのセッターが呼び出されます。カスタム・セッターは次のようなものです。

var stringRepresentation: String
    get() = this.toString()
    set(value) {
        setDataFromString(value) // 文字列を解析し、他のプロパティに値を代入
    }

Backing fields

Kotlinでは、フィールドはプロパティの一部としてのみ使用され、その値をメモリ内に保持します。
フィールドを直接宣言することはできません。
しかし、プロパティがバッキングフィールドを必要とするとき、Kotlinは自動的にそれを提供します。
このバッキングフィールドはfield識別子を用いてアクセサで参照することができます。

var counter = 0 // イニシャライザはバッキングフィールドを直接割り当てます。
    set(value) {
        if (value >= 0)
            field = value
            // counter = value // 実際の名前 'counter' を使用するとエラー
    }

field識別子は、プロパティのアクセッサにおいてのみ使用することができます。

バッキングフィールドは、そのプロパティが少なくともひとつのアクセサのデフォルト実装を使用しているか、カスタムアクセッサがfield識別子を通じてそれを参照している場合に、そのプロパティに対して生成されます。

たとえば、次のような場合はバッキングフィールドは発生しません。

val isEmpty: Boolean
    get() = this.size == 0

解答例

class PropertyExample() {
    var counter = 0
    var propertyWithCounter: Int? = null
        set(value) {
            field = value
            counter++
        }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?