ダウンキャストが必要となる例

open class Super {}
class A : Super() {
    fun f() {}
}

val x: Super = A()
x.f() // x は Super なので f メソッドがわからずエラー:

if+is演算子で分岐する

Kotlinでは実行箇所の文脈によって自動的に推論されてダウンキャストされる。

例えば上記例では if (x is A) でチェックすると、そのなかではxAのインスタンスであると判断されるので Aクラスのインスタンスメソッドf()が呼べるようになる。

open class Super {}
class A : Super() {
    fun f() {}
}

val x: Super = A()
if (x is A) {
  x.f() // ここでは x は A と確定しているのでエラーにならない
}

ifブロック内ではxAと確定するので、コンパイラがスマートキャスト(smart cast)という機能で自動的にxAにキャストしてくれる。

when+is演算子で分岐する

子クラスが複数あり、それぞれで分岐する場合にはelse ifも利用して以下のように書ける。

open class Super {}
class A : Super() {
    fun f() {}
}
class B : Super() {
    fun g() {}
}

val x: Super = A()
if (x is A) {
  x.f() // ここでは x は A と確定しているのでエラーにならない
} else if (x is B) {
  x.g() // ここでは x は B と確定しているのでエラーにならない
}

ただしwhenで分岐したほうがスッキリと書ける。

open class Super {}
class A : Super() {
    fun f() {}
}
class B : Super() {
    fun g() {}
}

val x : Super = A()
when(x) {
    is A -> x.f() // x は A と確定しているのでエラーにならない
    is B -> x.g() // x は B と確定しているのでエラーにならない
    else -> {}
}