Skip to content

Instantly share code, notes, and snippets.

@ohtsuchi
Last active November 27, 2017 05:05
Show Gist options
  • Save ohtsuchi/e09a95447b5278d851feecc3ba15b621 to your computer and use it in GitHub Desktop.
Save ohtsuchi/e09a95447b5278d851feecc3ba15b621 to your computer and use it in GitHub Desktop.
Kotlinスタートブック(赤べこ本) 第9章 の 写経

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

第9章 継承と抽象クラス


1. Class の 継承

list 9.1

  • superclass (継承元クラス) に open を付けていないので コンパイルエラー
class Person(val name: String) {
    fun introduceMyself() {
        println("I am $name.")
    }
}

class Student(name: String, val id: Long) : Person(name) // Error: This type is final, so it cannot be inherited from

list 9.2 open を付けて 継承を行っている例

// superclass で `name` を プロパティとして定義
open class Person(val name: String) {
    fun introduceMyself() {
        println("I am $name.")
    }
}

// subclass で `name` を 改めて定義する必要がない
// -> name には var(または val) を付けていない
class Student(name: String, val id: Long) : Person(name)

fun main(args: Array<String>) {
    val person: Person = Person("ゆたか")
    person.introduceMyself()      // I am ゆたか.

    val student: Student = Student("くみこ", 123)
    println(student.id)           // 123
    println(student.name)         // くみこ
    student.introduceMyself()     // I am くみこ.
}

2. member の override

list 9.3 method の override

open class Person(val name: String) {
    // `open`
    open fun introduceMyself() {
        println("I am $name.")
    }
}

class Student(name: String, val id: Long) : Person(name) {
    // `override`
    override fun introduceMyself() {
        println("I am $name(id=$id)")
    }
}

fun main(args: Array<String>) {
    val student: Student = Student("くみこ", 123)
    student.introduceMyself()     // I am くみこ(id=123)
}

list 9.4 superclass の実装を使う

  • super.メンバ
open class Person(val name: String) {
    open fun introduceMyself() {
        println("I am $name.")
    }
}

// list 9.4
class Student(name: String, val id: Long) : Person(name) {
    override fun introduceMyself() {
        println("-- 自己紹介 ここから --")
        super.introduceMyself()            // `super.メンバ`
        println("-- 自己紹介 ここまで --")
    }
}

fun main(args: Array<String>) {
    val student: Student = Student("くみこ", 123)
    student.introduceMyself()
}
  • 実行結果
-- 自己紹介 ここから --
I am くみこ.
-- 自己紹介 ここまで --

list 9.5 property の override

// list 9.5
// val の前に `open`
open class Person(open val name: String) {
    open fun introduceMyself() {
        println("I am $name.")
    }
}

// `override val`
class Student(override val name: String, val id: Long) : Person(name) {
    override fun introduceMyself() {
        println("I am $name(id=$id)")
    }
}

fun main(args: Array<String>) {
    val student: Student = Student("くみこ", 123)
    student.introduceMyself()     // I am くみこ(id=123)
}

3. Supertype と Subtype

list 9.6 Student (subtype) インスタンスへの参照を, Person (supertype) 型 の変数へ代入

  • 変数 person の 見かけ上の型 は Person (supertype)
  • 実体は Student (subtype) インスタンス
// list 9.5
open class Person(open val name: String) {
    open fun introduceMyself() {
        println("I am $name.")
    }
}

class Student(override val name: String, val id: Long) : Person(name) {
    override fun introduceMyself() {
        println("I am $name(id=$id)")
    }
}

fun main(args: Array<String>) {
    // list 9.6
    val person: Person = Student("たろう", 123)       // `Student` インスタンスへの参照を, `Person` 型 の変数へ代入
    person.introduceMyself()  // I am たろう(id=123)  // override した実装 が実行される
    person.id                 // コンパイルエラー
}

4. Any


5. abstract class (抽象クラス)

list 9.7 abstract class

// `abstract`
abstract class Greeter(val target: String) {
    // `abstract`
    abstract fun sayHello()
}

class EnglishGreeter(target: String) : Greeter(target) {
    // `override`
    override fun sayHello() {
        println("Hello, $target!")
    }
}
class JapaneseGreeter(target: String) : Greeter(target) {
    // `override`
    override fun sayHello() {
        println("こんにちは, $target!")
    }
}

fun main(args: Array<String>) {
    EnglishGreeter("Kotlin").sayHello() // Hello, Kotlin!
    JapaneseGreeter("Java").sayHello()  // こんにちは, Java!
    // 追記
    Greeter("Kotlin")  // コンパイルエラー(Cannot create an instance of an abstract class)
}

6. visibility (可視性)

6.1 Package

list 9.8 package の 宣言例

package sample.hoge
class Foo

list 9.9 import の 例

package sample.fuga

import sample.hoge.Foo          // (1)
import sample.fuga.Baz as Beer  // (2) `as` で 別名 import

class Baz

class Bar {
    fun doSomethingGood() {
        Foo()                   // (1) で import
        sample.hoge.Foo()       // fully qualified name (完全修飾名)
        Beer()                  // (2) で 別名 import
    }
}

6.2 top level における visibility modifier (可視性修飾子)

list 9.10 functions.kt

package sample

public fun publicFunction() {}
private fun privateFunction() {}
internal fun internalFunction() {}

list 9.11 main.kt

package sample

fun main(args: Array<String>) {
    publicFunction()   // OK
    privateFunction()  // コンパイルエラー( Cannot access 'privateFunction': it is private in file )
    // 追記
    internalFunction() // OK
}

class level における visibility modifier (可視性修飾子)

list 9.12 sample.kt

open class Foo {
    private fun privateMethod() {}
    protected fun protectedMethod() {}
}

class Bar : Foo() {
    fun execute() {
        privateMethod()   // コンパイルエラー (Cannot access 'privateMethod': it is invisible (private in a supertype) in 'Bar')
        protectedMethod() // subclass なので OK
    }
}

class Baz {
    fun execute(foo: Foo) {
        foo.protectedMethod() // コンパイルエラー (Cannot access 'protectedMethod': it is protected in 'Foo')
    }
}

list 9.13 private な constructor

  • primary constructor に 修飾子 や annotation を付ける場合
    • キーワード constructor を省略できない
open class Hoge private constructor()

class Fuga: Hoge() // コンパイルエラー (Cannot access '<init>': it is private in 'Hoge')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment