Catクラスを定義する。
クラスメソッドhogeを定義する。
class Cat {
class func hoge() -> String {
return "Cat::hoge"
}
}
Catクラスを受け取って、クラスメソッドhogeを呼ぶ関数を作る。
受け取る部分で出てくる 型の型 は 型名.Type
で書ける。
func callCatClassHoge(catClass: Cat.Type) -> String {
return catClass.hoge()
}
型の値を 型名.self
で取れる。
先ほどの関数にCatクラスを渡す。
callCatClassHoge(Cat.self) // => Cat::Hoge
クラスメソッドが呼びだせた。
Catのサブクラス、RoboCatクラスを定義する。
クラスメソッドはオーバライドできる。
class RoboCat : Cat {
override class func hoge() -> String {
return "RoboCat::hoge"
}
}
サブクラスはクラスに互換性がある。
つまり、RoboCat.self is Cat.Type == true
である。
よって、先ほどの関数にRoboCatクラスを渡せる。
callCatClassHoge(RoboCat.self) // => RoboCat::hoge
オーバライドした実装が呼び出された。
式の型の値を.dynamicType
で取得できる。
let a: Cat = Cat()
callCatClassHoge(a.dynamicType) // => Cat::hoge
aはCatのインスタンスだから、aの型はCatだ。
RoboCatで同じ事をすれば、
RoboCatのクラスメソッドが呼ばれる。
let b: RoboCat = RoboCat()
callCatClassHoge(b.dynamicType) // => RoboCat::hoge
dynamicTypeは動的に評価されているので、
静的にはCat型の式でも、式の型の値はRoboCatだ。
let c: Cat = b as Cat
callCatClassHoge(c.dynamicType) // => RoboCat::hoge
おわり🐱