クラスは、別のクラスからメソッド、プロパティ、および他の特徴を継承することができます。
あるクラスが別のクラスから継承するとき、継承するクラスをサブクラス、継承されるクラスをスーパークラスと呼びます。
今回は、Swiftの継承について以下の観点で解説します。
- ベースクラスの定義
- サブクラス化
- オーバーライド
参考本
[改訂新版]Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 WEB+DB PRESS plus
ベースクラスの定義
別のクラスから継承されるクラスのことを、ベースクラスと呼びます。
次の例では、ベースクラスVehicle を定義しています。
var currentSpeed = 0.0
var description: String {
return “traveling at \(currentSpeed) miles per hour”
}
func makeNoise() {
// 何もしない – 乗り物は必ずしも音を立てない
}
}
ベースクラス Vehicle は、makeNoise メソッドも定義しています。
このメソッドは、ベースの Vehicle インスタンスでは実際には何もしませんが、後で Vehicle のサブクラスによってカスタマイズされます。
ベースクラス Vehicle を実行します。
print(“Vehicle: \(someVehicle.description)”)
// Vehicle: traveling at 0.0 miles per hour
サブクラス化
サブクラスは、既存のクラスから特徴を継承し、改良することができます。
サブクラスにスーパークラスがあることを示すために、サブクラス名の後にスーパークラス名を記述し、コロンで区切ります。
// サブクラスの定義
}
次の例では、Vehicle をスーパークラスとするサブクラス Bicycle を定義しています。
var hasBasket = false
}
新しい Bicycle クラスは、currentSpeed や description プロパティと makeNoise() メソッドなどの、Vehicle のすべての特徴を自動的に獲得します。
継承する特徴に加えて、Bicycle クラスは新しいストアドプロパティ hasBasket をデフォルト値 false(プロパティを Bool 型と推論)で定義しています。
サブクラスをさらにサブクラス化することもできます。
オーバーライド
サブクラスは、スーパークラスから継承したインスタンスメソッド、タイプメソッド、インスタンスプロパティ、タイププロパティ、およびサブスクリプトの独自実装を持つことができます。
これをオーバーライドと呼びます。
継承した特徴をオーバーライドするには、override キーワードをオーバーライドする定義の前に付けます。
サブクラスでメソッド、プロパティ、サブスクリプトをオーバーライドするとき、オーバーライドの一部としてスーパークラスの実装を利用したい場合、スーパークラスのメソッド、プロパティ、サブスクリプトに super を付けてアクセスします。
例えば、オーバーライドされたメソッド someMethod() は、そのオーバーライド実装内で super.someMethod() とすることでスーパークラスの someMethod() を呼び出すことができます。
メソッドのオーバーライド
次の例では、Vehicle の新しいサブクラス Train を定義し、Vehicle から継承した makeNoise() メソッドを Train はオーバーライドしています。
override func makeNoise() {
print(“Choo Choo”)
}
}
Train のインスタンスを生成して makeNoise() メソッドを呼び出す場合、サブクラス Train のメソッドが呼び出されます。
train.makeNoise()
// Prints “Choo Choo”
プロパティのオーバーライド
インスタンスプロパティやタイププロパティに独自の getter や setter を持たせることや、プロパティ値の変更を監視するためにプロパティオブザーバを追加することで、継承したプロパティをオーバーライドすることができます。
次の例では、Vehicle のサブクラスである新しいクラス Car を定義しています。Car クラスには、デフォルトの整数値が 1 のストアドプロパティ gear を定義しています。
Car クラスは、Vehicle から継承する description プロパティを、現在のギアを含む説明となるようにオーバーライドもしています。
var gear = 1
override var description: String {
return super.description + ” in gear \(gear)”
}
}
Car クラスのインスタンスを生成して gear と currentSpeed を設定した場合、description プロパティは Car クラス内で定義した付加情報のある説明を返すようになります。
car.currentSpeed = 25.0
car.gear = 3
print(“Car: \(car.description)”)
// Car: traveling at 25.0 miles per hour in gear 3
プロパティオブザーバのオーバーライド
継承したプロパティにプロパティオブザーバを追加することができます。
これによって、プロパティの実装にかかわらず、継承したプロパティ値の変更時に通知されるようにすることができます。
次の例では、Car のサブクラスである新しいクラス AutomaticCar を定義しています。
AutomaticCar クラスは、現在速度をもとに自動的に適切なギアを選択する自動変速装置を持つ車を表現しています。
override var currentSpeed: Double {
didSet {
gear = Int(currentSpeed / 10.0) + 1
}
}
}
AutomaticCarを実行してみます。
automatic.currentSpeed = 35.0
print(“AutomaticCar: \(automatic.description)”)
// AutomaticCar: traveling at 35.0 miles per hour in gear 4
AutomaticCar インスタンスの currentSpeed プロパティに設定したとき、プロパティの didSet オブザーバが新しい速度に合う適切なギアをインスタンスの gear プロパティに設定します。
具体的には、プロパティオブザーバは新しい currentSpeed の値を 10 で割り、整数に切り捨て、1 を足したギアを選択します。速度 35.0 は、ギア 4 となります。
オーバーライドの防止
メソッド、プロパティ、サブスクリプトがオーバーライドされることを final で防ぐことができます。
そうするには、メソッド、プロパティ、サブスクリプトのキーワードの前に final を、final var, final func, final class func, final subscript のように記述します。
以上、今回は、Swiftの継承について解説しました。