Josh Skeen, David Greenhalgh著　『Kotlinプログラミング』　章末問題に挑戦(第１３章)

　[Josh Skeen, David Greenhalgh著『Kotlinプログラミング』](https://www.shoeisha.co.jp/book/detail/9784798160191)には章末問題がある。残念なことに解答がないので、[第１０章](https://qiita.com/guijiu/items/9619abd4d5bf3488e58f)に引き続き本を読み進めながら答案を記述する。
　もし回答に間違いや意見があれば、ぜひご指摘いただきたい。

#第１３章　章末問題 回答案

##13.7　チャレンジ！　エクスカリバーの謎
　本書 リスト13-16,17の動作には少し悩んだので、復習を兼ねて次のコードを実行して初期化について挙動を確認した。（以下に示すD5クラス、D6クラスの動作が理解できていなかった。）
　ポイントはfiledキーワードとプロパティー、初期化ブロック(init{...})に与えられた値の関係、挙動を理解することだと思います。コード横にコメントを記入しましたが、うまく説明ができませんでしたので、以下のコードをコンパイルして動作を確認してください。

###C1クラス
```Kotlin:C1.kt
fun main() {
    // クラスC1のプロパティを呼び出す
    println()
    println("C1をインスタンス化")
    val c1 = C1()
    println("クラスC1インスタンス直後のpropty: ${c1.propty}")    // abc
}

// ゲッター・セッターなし（ゲッター機能あり、セッター機能なし）
class C1 {
    val propty = "abc"
}
```
###C2クラス
```Kotlin:C2.kt
fun main() {
    // クラスC2のプロパティに書き込み、それを呼び出す
    println()
    println("C2をインスタンス化")
    var c2 = C2()   // 書き換えをするため変数定義のキーワードをvalからvarに変更
    println("クラスC2インスタンス直後のpropty: ${c2.propty}")    // abc
    c2.propty = "def"
    println("C2のpropty: ${c2.propty}")   // def
}

// クラスプロパティにゲッターセッターを追加する
class C2 {
    var propty = "abc"  // 書き換えをするため変数定義のキーワードをvalからvarに変更
        get() = field   // fieldは、この場合、proptyのことである
        set(value) {    // valueは、この場合、セッターによって受け取る値である
            field = value
        }
}
```

###C3クラス
```Kotlin:C3.kt
fun main() {
    // クラスC3のコンストラクタを用いて初期値を与える
    println()
    println("コンストラクタを用いてプロパティに初期値ghiを与える")
    var c3 = C3("ghi")
    println("クラスC3のpropty: ${c3.propty}")    // ghi
    println("クラスC3のproptyをセッターを用いてdefに書き換える")
    c3.propty = "def"
    println("クラスC3のpropty: ${c3.propty}")    // def
    println()
}

// クラスコンストラクタを追加する
class C3(_propty: String){  // _proptyはこの波括弧{...}内をスコープとする使い捨ての変数
    var propty = _propty    // コンストラクタを使ってコンストラクタで与えられた値_proptyを使って、proptyを初期化
        get() = field       // c3.proptyを要求された時に、filedを通してproptyの値が出力される
        set(value) {        // c3.propty="ｘｘｘ"で値が与えられたときに、valueがｘｘｘという値になり、fieldに値が渡される。このときfieldはproptyのことである。
            field = value
        }
}
```

###D1クラス
```Kotlin:D1.kt
fun main() {
    println()
    println("D1をインスタンス化")
    val d1 = D1()
    println("クラスD1インスタンス化直後に、ゲッターを通して得たpropty: ${d1.propty}")   // Abc
}

// abcという文字列の先頭文字を大文字に変えて、proptyに与える。
class D1 {
    val propty = "abc".capitalize()
}
```

###D2クラス
```Kotlin:D2.kt
fun main() {
    //
    println()
    println("D2をインスタンス化")
    var d2 = D2()   // 書き換えをするため変数定義のキーワードをvalからvarに変更
    println("クラスD2インスタンス化直後に、ゲッターを通して得たpropty: ${d2.propty}")   // Abc
    d2.propty = "mno"
    println("D2のセッターにmnoを与えた直後に、ゲッターを通して得たpropty: ${d2.propty}")   // Mnodef
}

// クラスプロパティにゲッターセッターを追加する
class D2 {
    var propty = "abc"
        get() = field.capitalize()  // fieldはproptyを示し、この値を加工し、get()で出力する
        set(value) {
            field = value + "def"   // セッターで受け取った値をvalueを通して加工して（この場合、valueにdefを加えて)、field(この場合propty)に渡す。
        }
}
```

###D3クラス
```Kotlin:D3.kt
fun main() {
    //
    println()
    println("D3のプライマリコンストラクタにjklを与えインスタンス化")
    var d3 = D3("jkl")
    println("クラスD3インスタンス化直後に、ゲッターを通して得たpropty: ${d3.propty}")   // Jkl
    d3.propty = "mno"
    println("D3のセッターにmnoを与えた直後に、ゲッターを通して得たpropty: ${d3.propty}")   // Mnodef
}

// クラスに引数ありのプライマリコンストラクタを追加する
class D3(_propty: String) {
    var propty = _propty    // コンストラクタを通して得た値_proptyをproptyに与える
        get() = field.capitalize()
        set(value) {
            field = value + "def"
        }
}
```

###D4クラス
```Kotlin:D4.kt
fun main() {
    //
    println()
    println("D4コンストラクタにjklを与えインスタンス化")
    var d4 = D4("jkl")
    println("クラスD4インスタンス化直後に、ゲッターを通して得たpropty: ${d4.propty}")   // Abc
    d4.propty = "mno"
    println("D4のセッターにmnoを与えた直後に、ゲッターを通して得たpropty: ${d4.propty}")   // Mnodef

}
// 引数ありコンストラクタではあるが、受け取った_proptyはproptyに与えることなく、proptyにはabcを与える
class D4(_propty: String) {
    var propty = "abc"  // proptyにabcを与える
        get() = field.capitalize()
        set(value) {
            field = value + "def"
        }
}
```

###D5クラス
```Kotlin:D5.kt
fun main() {
    //
    println()
    println("D5のプライマリコンストラクタにjklを与えインスタンス化")
    var d5 = D5("jkl")
    println("クラスD5インスタンス化直後に、ゲッターを通して得たpropty: ${d5.propty}")   // Jkldef
    d5.propty = "mno"
    println("D5のセッターにmnoを与えた直後に、ゲッターを通して得たpropty: ${d5.propty}")   // Mnodef

    //
    println()
    println("D5 引数なしセカンドコンストラクタをインスタンス化")
    var d51 = D5()
    println("クラスD4(引数なしコンストラクタ)インスタンス化直後のプロパティ: ${d51.propty}")     // Ghidef
    d51.propty = "mno"
    println("D5のセッターにmnoを与えた直後のプロパティー: ${d51.propty}")      // Mnodef
}

// 初期化ブロックinit{...}を追加
class D5(_propty: String) {
    var propty = "abc"  // init初期化ブロックがあると、abcで初期化することはなく、
        // init{...}ブロックの中の式に従って動作する。
        get() = field.capitalize()
        set(value) {
            field = value + "def"
        }

    init{
        propty = _propty    // コンストラクタで与えられた値_proptyは、先ず直接proptyに代入されるのではなく、
        // proptyのセッターに与えられる。すなわちvalueが_proptyになり、
        // filedが_propty+"def"になり、最後にpropty(=filed)=_propty+"def"になる
        // この動きがinit{...}の挙動を理解する上での難点であった
    }

    constructor() : this("ghi")
}
```
###D6クラス
```Kotlin:D6.kt
fun main() {
    //
    println()
    println("D6のプライマリコンストラクタにjklを与えインスタンス化")
    var d6 = D6("jkl")
    println("クラスD6インスタンス化直後に、ゲッターを通して得たpropty: ${d6.propty}")   // Jkldef
    d6.propty = "mno"
    println("D5のセッターにmnoを与えた直後に、ゲッターを通して得たpropty: ${d6.propty}")   // Mnodef
}

// 初期化ブロックinit{...}を追加（D5クラスの"var propty ="で与える値が"abc"から_proptyに変更）
class D6(_propty: String) {
    var propty = _propty  // D6のプロパティーに_proptyを与えるが、この_proptyはこの行では何も寄与せず、
        // init{...}ブロックの中の式に従って動作する。
        get() = field.capitalize()
        set(value) {
            field = value + "def"
        }

    init{
        propty = _propty    // コンストラクタに与えられた値は、D5クラスのinit{...}と同じ動作をする。
    }

    constructor() : this("ghi")
}

```


[第２章チャレンジ！答案](https://qiita.com/guijiu/items/dd3313f2a73401e29bc4)
[第３章チャレンジ！答案](https://qiita.com/guijiu/items/672b8daf014d4e6bb346)
[第４章チャレンジ！答案](https://qiita.com/guijiu/items/08dfa397b989b7ecdb3a)
[第７章チャレンジ！答案](https://qiita.com/guijiu/items/452cfa51bee6c4a4af9d)
[第８章チャレンジ！答案](https://qiita.com/guijiu/items/9a7871b1e41bdabd85e7)
[第１０章チャレンジ！答案](https://qiita.com/guijiu/items/9619abd4d5bf3488e58f)
[第１３章チャレンジ！答案](https://qiita.com/guijiu/items/5eda8682b1c05fa48c7d)
[第１５章チャレンジ！答案](https://qiita.com/guijiu/items/0f67138483e12641dfc3)