Skip to content

Instantly share code, notes, and snippets.

@ohtsuchi
Last active November 6, 2017 06:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ohtsuchi/3435ef982e6714d63b95213b571b7fba to your computer and use it in GitHub Desktop.
Save ohtsuchi/3435ef982e6714d63b95213b571b7fba to your computer and use it in GitHub Desktop.
Kotlinスタートブック(赤べこ本) 第8章 の 写経

Kotlinスタートブック(赤べこ本) 第8章 の 写経

第8章 クラスとそのメンバ


1. Class の定義と Instance 化

list 8.1 最も単純な class 定義, list 8.2

// list 8.1
class MyClass  // Default Constructor (引数を取らない Constructor) が 自動で生成される

// list 8.2
fun main(args: Array<String>) {
    val m: MyClass = MyClass()
    println(m) // MyClass@27c170f0
}

2. Method

list 8.3

class Greeter {
    fun greet(name: String) {
        println("Hello, $name!")
    }
}

fun main(args: Array<String>) {
    val g = Greeter()
    g.greet("Kotlin") // Hello, Kotlin!
}

3. Property

list 8.4, list 8.5

// list 8.4
class Person {
    var name: String = ""
    var age: Int = 0
}

// list 8.5
fun main(args: Array<String>) {
    val hanako = Person()
    println(hanako.name) //
    println(hanako.age)  // 0

    hanako.name = "はなこ"
    hanako.age = 25
    println(hanako.name) // はなこ
    println(hanako.age)  // 25
}

3.1 backing field

list 8.6 backing field を持たない property, list 8.7 custom getter の 省略記法

class Person {
    var name: String = ""
    var age: Int = 0

    // list 8.6
    val nameLength: Int
        get() :Int {             // custom getter
            return this.name.length
        }

    // list 8.7
    val nameLength2: Int
        get() = this.name.length // custom getter の 省略記法
}

fun main(args: Array<String>) {
    val hanako = Person()
    hanako.name = "はなこ"
    println(hanako.nameLength)  // 3
    println(hanako.nameLength2) // 3
}

list 8.8 custom setter の例

  • custom setter
    • set(value) { .. }
  • field = backing field を表す 暗黙の変数
class Person {
    var name: String = ""
        set(value) { // custom setter
            println("${value} がセットされました")
            field = value // `field` = backing field を表す 暗黙の変数
        }

    var age: Int = 0
    val nameLength: Int
        get() :Int {
            return this.name.length
        }
}

fun main(args: Array<String>) {
    val hanako = Person()
    hanako.name = "はなこ" // はなこ がセットされました
    println(hanako.name)   // はなこ
}

3.2 遅い初期化

  • lateinit
  • -> 第13章-14 アノテーション (p217) 参照
  • -> 第17章-2 Dagger2 (p291, p293) 参照

list 8.9

class MyClass {
    lateinit var foo: String  // `lateinit var`
}

fun main(args: Array<String>) {
    val m = MyClass()
    m.foo // UninitializedPropertyAccessException (初期化される前に アクセス)
}

4. this


5. Constructor と Initializer

list 8.10 引数を取る constructor, list 8.11 Constructor の引数をそのまま property に

// list 8.10
class Rational constructor(n: Int, d: Int) {
    val numerator: Int = n
    val denominator: Int = d
}

// list 8.11 `val`, `var` -> 引数をそのまま property に
class Rational2(val numerator: Int, val denominator: Int) // `constructor` 省略可能

fun main(args: Array<String>) {
    val half = Rational(1, 2)
    println(half.numerator)   // 1
    println(half.denominator) // 2

    val half2 = Rational2(1, 2)
    println(half2.numerator)   // 1
    println(half2.denominator) // 2
}
  • constructor
    • 省略可能 (コンストラクタ に 修飾子 や アノテーション を付加しない場合)
    • -> 第9章-6 可視性 (p140) 参照

5.1 Secondary Constructor

list 8.12 Secondary constructor

class Rational(val numerator: Int, val denominator: Int) {
    constructor(numerator: Int) : this(numerator, 1) // `:` を挟んで primary constructor を呼び出し
}

fun main(args: Array<String>) {
    val half = Rational(1, 2)
    println("${half.numerator}/${half.denominator}")   // 1/2

    val five = Rational(5)
    println("${five.numerator}/${five.denominator}")   // 5/1
}

list 8.13 コンストラクタ引数 に デフォルト値 を設定

class Rational(val numerator: Int, val denominator: Int = 1)

fun main(args: Array<String>) {
    val half = Rational(1, 2)
    println("${half.numerator}/${half.denominator}")   // 1/2

    val five = Rational(5)
    println("${five.numerator}/${five.denominator}")   // 5/1
}

5.2 Initializer

list 8.14 Initializer の例

  • 分母が 0Rational のインスタンスを生成しないように
    • initializer に 事前条件
class Rational(val numerator: Int, val denominator: Int = 1) {
    init {
        // 要求に反した場合, 例外を throw する 標準ライブラリの関数
        require(denominator != 0)
    }
}

fun main(args: Array<String>) {
    Rational(1, 1)
    Rational(1, 0) // IllegalArgumentException: Failed requirement.
}

6. Extension

list 8.15 String を引数にとる function, list 8.16

// list 8.15 `String` を引数にとる function
fun countWords(s: String): Int =
        s.split("""\s""".toRegex()).size

fun main(args: Array<String>) {
    // list 8.16
    val c = countWords("I like Kotlin")
    println(c) // 3
}

list 8.17, list 8.18 String に対する extension function, list 8.19 String に対する extension property

// list 8.18 `String` に対する extension function
fun String.countWords(): Int =
        this.split("""\s""".toRegex()).size

// list 8.19 `String` に対する extension property
val String.countWords: Int
    get() = split("""\s""".toRegex()).size       // `this.` は省略可能

fun main(args: Array<String>) {

    // list 8.17
    println("I like Kotlin".countWords()) // 3
    // list 8.19
    println("I like Kotlin".countWords)   // 3
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment