サブクラスは、スーパークラスから継承したインスタンスメソッド、タイプメソッド、インスタンスプロパティ、タイププロパティ、およびサブスクリプトの独自実装を持つことができます。これをオーバーライドと呼びます。
継承した特徴をオーバーライドするには、override
キーワードをオーバーライドする定義の前に付けます。そうすることで、オーバーライドする意図があることと、定義を誤っていないことを明確にします。偶然にオーバーライドできてしまうと予期しない挙動を引き起こすため、override
キーワードの無いオーバーライドはコンパイル時にエラーと診断されます。
override
キーワードは、オーバーライドしているクラスのスーパークラスに、オーバーライドと一致する宣言があることをチェックするよう Swift コンパイラに促します。このチェックにより、オーバーライドの定義が正しいことを確実にすることができます。
スーパークラスのメソッド、プロパティ、サブスクリプトにアクセス
サブクラスでメソッド、プロパティ、サブスクリプトをオーバーライドするとき、オーバーライドの一部としてスーパークラスの実装を利用すると効果的な場合があります。例えば、既存実装の振る舞いを改良することや、継承した変数に変更した値を保管することができます。
こういった場面で、スーパークラスのメソッド、プロパティ、サブスクリプトに super
を付けてアクセスします。
- オーバーライドされたメソッド
someMethod()
は、そのオーバーライド実装内でsuper.someMethod()
とすることでスーパークラスのsomeMethod()
を呼び出すことができます。 - オーバーライドされたプロパティ
someProperty
は、そのオーバーライドしている getter または setter 実装内でsuper.someProperty
とすることでスーパークラスのsomeProperty
にアクセスすることができます。 - オーバーライドされたサブスクリプトの
someIndex
は、オーバーライドしているサブスクリプト実装内からsuper[someIndex]
としてスーパークラスの同じサブスクリプトにアクセスすることができます。
メソッドをオーバーライド
サブクラス内でインスタンスメソッドやタイプメソッドに別の実装を持たせることで、継承したメソッドをオーバーライドすることができます。
次の例では、Vehicle
の新しいサブクラス Train
を定義し、Vehicle
から継承した makeNoise()
メソッドを Train
はオーバーライドしています。
class Train: Vehicle {
override func makeNoise() {
print("Choo Choo")
}
}
Train
のインスタンスを生成して makeNoise()
メソッドを呼び出す場合、サブクラス Train
のメソッドが呼び出されます。
let train = Train()
train.makeNoise()
// Prints "Choo Choo"
プロパティをオーバーライド
インスタンスプロパティやタイププロパティに独自の getter や setter を持たせることや、プロパティ値の変更を監視するためにプロパティオブザーバを追加することで、継承したプロパティをオーバーライドすることができます。
プロパティの getter と setter をオーバーライド
継承したプロパティの実装がストアドかコンピューテッドかにかかわらず、継承したプロパティをオーバーライドするために getter(および適切な場合には setter)を持たせることができます。継承したプロパティの性質として、ストアドかコンピューテッドかはサブクラスからはわからず、継承したプロパティの名前と型だけがわかります。オーバーライドがスーパークラスのプロパティと同じ名前と型を持っているかをコンパイラがチェックできるよう、プロパティの名前と型の両方を示す必要があります。
継承した読み取り専用のプロパティを、サブクラスのプロパティオーバーライドで getter と setter の両方を定義して読み書き可能なプロパティにすることができます。一方で、読み書き可能なプロパティを、読み取り専用のプロパティとすることはできません。
someProperty
がオーバーライドしているプロパティの名前であるとき、getter から単に super.someProperty
を返して継承した値を通すことができます。
次の例では、Vehicle
のサブクラスである新しいクラス Car
を定義しています。Car
クラスには、デフォルトの整数値が 1
のストアドプロパティ gear
を定義しています。Car
クラスは、Vehicle
から継承する description
プロパティを、現在のギアを含む説明となるようにオーバーライドもしています。
class Car: Vehicle {
var gear = 1
override var description: String {
return super.description + " in gear \(gear)"
}
}
description
プロパティのオーバーライドは、Vehicle
クラスの description
プロパティを返す super.description
を呼び出すことで始めます。そして、Car
クラスの description
は、現在のギアについての情報を説明の末尾に追加しています。
Car
クラスのインスタンスを生成して gear
と currentSpeed
を設定した場合、description
プロパティは Car
クラス内で定義した付加情報のある説明を返すようになります。
let car = Car()
car.currentSpeed = 25.0
car.gear = 3
print("Car: \(car.description)")
// Car: traveling at 25.0 miles per hour in gear 3
プロパティオブザーバをオーバーライド
継承したプロパティにプロパティオブザーバを追加することができます。プロパティの実装にかかわらず、継承したプロパティ値の変更時に通知されるようにすることができます。プロパティオブザーバの詳細な情報は、Property Observers を確認してください。
継承した定数のストアドプロパティや、継承した読み取り専用のコンピューテッドプロパティには、プロパティオブザーバを追加することはできません。これらのプロパティの値を設定することはできないため、オーバーライドの一部として willSet
や didSet
の実装を持たせることは適切ではありません。
また、同じプロパティにオーバーライドの setter と、オーバーライドのプロパティオブザーバとの両方を持たせることもできません。プロパティ値の変更を監視したい場合で、かつすでにそのプロパティに独自の setter を定義している場合には、その setter 内から値の変更を監視することができます。
次の例では、Car
のサブクラスである新しいクラス AutomaticCar
を定義しています。AutomaticCar
クラスは、現在速度をもとに自動的に適切なギアを選択する自動変速装置を持つ車を表現しています。
class AutomaticCar: Car {
override var currentSpeed: Double {
didSet {
gear = Int(currentSpeed / 10.0) + 1
}
}
}
AutomaticCar
インスタンスの currentSpeed
プロパティに設定したとき、プロパティの didSet
オブザーバが新しい速度に合う適切なギアをインスタンスの gear
プロパティに設定します。具体的には、プロパティオブザーバは新しい currentSpeed
の値を 10
で割り、整数に切り捨て、1
を足したギアを選択します。速度 35.0
は、ギア 4
となります。
let automatic = AutomaticCar()
automatic.currentSpeed = 35.0
print("AutomaticCar: \(automatic.description)")
// AutomaticCar: traveling at 35.0 miles per hour in gear 4
Portions of this page are translations based on work created and shared by Apple and used according to terms described in the Creative Commons Attribution 4.0 International License.