サブクラスは、スーパークラスから継承したインスタンスメソッド、タイプメソッド、インスタンスプロパティ、タイププロパティ、およびサブスクリプトの独自実装を持つことができます。これをオーバーライドと呼びます。

継承した特徴をオーバーライドするには、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 の両方を定義して読み書き可能なプロパティにすることができます。一方で、読み書き可能なプロパティを、読み取り専用のプロパティとすることはできません。

NOTE
プロパティオーバーライドの一部として setter を定義する場合、そのオーバーライドに getter も定義する必要があります。オーバーライドの getter 内で継承したプロパティの値を変更したくない場合には、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 を確認してください。

NOTE

継承した定数のストアドプロパティや、継承した読み取り専用のコンピューテッドプロパティには、プロパティオブザーバを追加することはできません。これらのプロパティの値を設定することはできないため、オーバーライドの一部として 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.