継承

クラスは、メソッド、プロパティ、およびその他の特性を別のクラスから継承できます。あるクラスが別のクラスを継承する場合、継承するクラスはサブクラスと呼ばれ、継承するクラスはスーパークラスと呼ばれます。継承は、クラスをSwiftの他の型と区別する基本的な動作です。

Swiftのクラスは、スーパークラスに属するメソッド、プロパティ、およびサブスクリプトを呼び出してアクセスでき、それらのメソッド、プロパティ、およびサブスクリプトの独自のオーバーライドバージョンを提供して、動作を調整または変更できます。Swiftは、オーバーライド定義に一致するスーパークラス定義があることを確認することにより、オーバーライドが正しいことを確認するのに役立ちます。

クラスは、プロパティの値が変更されたときに通知を受けるために、継承されたプロパティにプロパティオブザーバーを追加することもできます。プロパティオブザーバーは、格納されたプロパティまたは計算されたプロパティとして最初に定義されたかどうかに関係なく、任意のプロパティに追加できます。

ベースクラスの定義

別のクラスを継承しないクラスは、ベースクラスと呼ばれます。

注意

Swiftクラスは、普遍的なベースクラスを継承しません。スーパークラスを指定せずに定義したクラスは、自動的にベースクラスになります。

// ベースクラスの例
class Vehicle {
    var currentSpeed = 0.0
    var description: String {
        return "traveling at \(currentSpeed) miles per hour"
    }
    func makeNoise() {
        // do nothing - an arbitrary vehicle doesn't necessarily make a noise
    }
}

// 新しいインスタンスを作成
let someVehicle = Vehicle()
print("someVehicle.description")

サブクラス化

サブクラス化とは、既存のクラスに基づいて新しいクラスを作成することです。サブクラスは、既存のクラスから特性を継承し、新しい特性を追加することもできます。

// サブクラスの定義:スーパークラス名の前にコロンで区切ってサブクラス名を記述
class SomeSubclass: SomeSuperclass {
    // subclass definition goes here
}

// 例
class Bicycle: Vehicle {
    var hasBasket = false
}

let bicycle = Bicycle()
bicycle.hasBasket = true
bicycle.currentSpeed = 15.0

// 例:サブクラス自体をサブクラス化
class Tandem: Bicycle {
    var currentNumberOfPassengers = 0
}

let tandem = Tandem()
tandem.hasBasket = true
tandem.currentNumberOfPassengers = 2
tandem.currentSpeed = 22.0
print("tandem.description")

オーバーライド

サブクラスは、スーパークラスから継承するインスタンスメソッド、タイプメソッド、インスタンスプロパティ、タイププロパティ、またはサブスクリプトの独自のカスタム実装を提供できます。これはオーバーライドと呼ばれます

継承される特性をオーバーライドするには、オーバーライド定義の前にoverrideキーワードを付けます。overrideキーワードのないオーバーライドは、コードのコンパイル時にエラーになります。

スーパークラスのメソッド、プロパティ、およびサブスクリプトへのアクセス

super接頭辞を使用して、メソッド、プロパティ、またはサビスクリプトのスーパークラスバージョンにアクセスします。

  • 名前付きのオーバーライドされたメソッド: super.someMethod()
  • 呼び出されたオーバーライドされたプロパティ: super.someProperty
  • オーバーライドされたサブスクリプト: オーバーライドされたサブスクリプト実装内で super[someIndex] として呼び出す

メソッドのオーバーライド

継承されたインスタンスまたはタイプメソッドをオーバーライドして、サブクラス内のメソッドの調整済み実装または代替実装を提供できます。

次の例では、新しいサブクラス定義Vehicle呼ばTrainオーバーライド、makeNoise()方法をそのTrainから継承Vehicle

// メソッドのオーバーライド例
class Train: Vehicle {
    override func makeNoise() {
        print("Choo Choo")
    }
}

let train = Train()
train.makeNoise()
// Prints "Choo Choo"

プロパティのオーバーライド

継承されたインスタンスまたはタイププロパティをオーバーライドして、そのプロパティに独自のカスタムゲッターとセッターを提供したり、プロパティオブザーバーを追加して、基になるプロパティ値が変更されたときにオーバーライドするプロパティを監視できるようにすることができます。

プロパティのゲッターとセッターのオーバーライド

継承されたプロパティがソースで格納または計算されたプロパティとして実装されているかどうかに関係なく、カスタムゲッター(および適切な場合はセッター)を提供して、継承されたプロパティをオーバーライドできます。継承されたプロパティの格納または計算された性質は、サブクラスでは認識されません。継承されたプロパティが特定の名前と型を持っていることだけがわかります。オーバーライドが同じ名前とタイプのスーパークラスプロパティに一致することをコンパイラがチェックできるようにするには、オーバーライドするプロパティの名前とタイプの両方を常に指定する必要があります。

サブクラスプロパティのオーバーライドでゲッターとセッターの両方を提供することにより、継承された読み取り専用プロパティを読み取り/書き込みプロパティとして提示できます。ただし、継承された読み取り/書き込みプロパティを読み取り専用プロパティとして提示することはできません。

注意

プロパティのオーバーライドの一部としてセッターを提供する場合は、そのオーバーライドのゲッターも提供する必要があります。オーバーライドするゲッター内で継承されたプロパティの値を変更したくない場合は、ゲッターから戻ることで継承された値super.somePropertyを単に渡すことができます。ここで、somePropertyはオーバーライドするプロパティの名前です。

プロパティオブザーバーのオーバーライド

プロパティのオーバーライドを使用して、継承されたプロパティにプロパティオブザーバーを追加できます。これにより、プロパティが最初にどのように実装されたかに関係なく、継承されたプロパティの値が変更されたときに通知を受けることができます。

注意

継承された定数格納プロパティまたは継承された読み取り専用の計算プロパティにプロパティオブザーバーを追加することはできません。これらのプロパティの値は設定できないため、オーバーライドの一部としてwillSetまたはdidSet実装を提供することは適切ではありません。

また、同じプロパティにオーバーライドセッターとオーバーライドプロパティオブザーバーの両方を指定することはできません。プロパティの値の変更を監視する必要があり、そのプロパティのカスタムセッターを既に提供している場合は、カスタムセッター内から値の変更を簡単に監視できます。

// プロパティオブザーバーのオーバーライドの例
class AutomaticCar: Car {
    override var currentSpeed: Double {
        didSet {
            gear = Int(currentSpeed / 10.0) + 1
        }
    }
}

let automatic = AutomaticCar()
automatic.currentSpeed = 35.0
print("AutomaticCar: \(automatic.description)")
// AutomaticCarインスタンスのcurrentSpeed を設定するたび、プロパティのdidSetオブザーバーは、インスタンスのgearプロパティを適切なギアにセットします。
// AutomaticCar: traveling at 35.0 miles per hour in gear 4

オーバーライドの防止

メソッド、プロパティ、またはサブスクリプトが final としてマークされることにより、それらがオーバーライドされるのを防ぐことができます。

// オーバーライドを禁止するキーワード final
final var
final func
final class func
final subscript

サブクラスのfinalメソッド、プロパティ、またはサブスクリプトをオーバーライドしようとすると、コンパイル時エラーとなります。

クラス定義でキーワードの前に final 修飾子を記述することにより、クラス全体を最終としてマークできます。final クラスをサブクラス化しようとすると、コンパイル時エラーとして報告されます。

投稿者: admin

Free Software Engineer

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です