var text: String = "Hello"
var i: Int? = Int(text)
var animal: Animal = Poodle()
animal.breathe()
//animal.chokomakaRun() //←これはエラー。animal変数のデータ型がpoodleではなくてAnimalだから
var poodle = animal as? Poodle //animalをpoodle型にキャスト
poodle?.chokomakaRun()
poodle?.breathe()
class Animal {
func breathe() {
print("呼吸する")
}
}
class Dog: Animal {
func bark() {
print("吠える")
}
}
//AnimalでもあるしDogでもある
class Poodle: Dog {
func chokomakaRun() {
print("ちょこまか")
}
}
詳しくみていきます。
Animalクラスが存在し、呼吸する関数があります。
そしてDogクラスはそのAnimalクラスを継承し、bark関数とbreathe関数が使えます。
さらにさらに、Poodleクラスがあり、それはDogクラスを継承し、そのDogクラスはAnimalクラスを継承しているため、
PoodleクラスではchokomakaRun関数とbark関数とbreathe関数が使えます。
var animal: Animal = Poodle()
animal.breathe()
var poodle = animal as? Poodle //animalをpoodle型にキャスト
poodle?.chokomakaRun()
poodle?.breathe()
//animal.chokomakaRun() //エラーになる理由: animal変数のデータ型がpoodleではなくてAnimalだから
class Animal {
func breathe() {
print("呼吸する")
}
}
上記で述べたように、PoodleはAnimalを継承しているのでAnimal型の変数にPoodleのインスタンスを作ることが出来ます。
そのため、poodleインスタンスが入ったanimal関数では、Animal クラスが持っていたbreathe関数を使うことが出来るわけです。
一方で、Animalクラスのanimalで、Poodleクラスが持つchokomakaRun関数を使うことは出来るでしょうか?
結論からいうと、出来ません。
animal変数はAnimal型であり、Animalクラスが持つ関数はbreatheのみだからです。
ではどのようにすればAnimal型のanimal変数が、Poodle型が持つchokomakaRun関数を使えるでしょうか。
ここでキャストが必要になります。ようは型を合わせるわけですね。
var animal: Animal = Poodle()
animal.breathe()
var poodle = animal as? Poodle //animalをpoodle型にキャスト
poodle?.chokomakaRun()
poodle?.breathe()
このようにしてAnimal型のanimal変数をPoodle型に変更することができます。(?をつけているので、オプショナルになります。)
型をこのように変換し、poodleという変数にPoodle型に変更されたanimal変数を入れました。
このpoodle変数ではpoodleクラスで使用できた、chokomakaRun関数とbark関数とbreathe関数が使えるようになりました。
継承の大元、一番抽象的なクラスAnimalから一番具体的なPoodleに型を変えたことで、Poodleの関数が使えるようになった感じです。