迅速な継承
継承は、あるクラスが別のクラスのメソッドと属性を取得することとして理解できます。
クラスが他のクラスを継承する場合、継承するクラスはサブクラスと呼ばれ、継承されたクラスはスーパークラス(または親クラス)と呼ばれます
Swiftでは、クラスはスーパークラスのメソッド、プロパティ、サブスクリプトを呼び出してアクセスできます、そしてそれらはオーバーライドできます。
クラス内の継承されたプロパティのプロパティ オブザーバーを追加することもできます。
Base Class
他のクラスを継承しないクラスをBase Classと呼びます。
次の例では、基本クラス StudDetails を定義し、生徒 (stname) と各科目の得点 (mark1、mark2、mark3) を記述します:
class StudDetails { var stname: String! var mark1: Int! var mark2: Int! var mark3: Int! init(stname: String, mark1: Int, mark2: Int, mark3: Int) { self.stname = stname self.mark1 = mark1 self.mark2 = mark2 self.mark3 = mark3 } } let stname = "swift" let mark1 = 98 let mark2 = 89 let mark3 = 76 print(stname) print(mark1) print(mark2) print(mark3)
上記のプログラムの実行の出力結果は次のとおりです:
swift 98 89 76
swift 98 89 76
サブクラス
サブクラス化とは、既存のクラスに基づいて新しいクラスを作成することを指します。
あるクラスのスーパークラスを指定するには、サブクラス名の後にスーパークラス名をコロン(:)で区切って記述します
class SomeClass: SomeSuperclass { // 类的定义 }
例
以下の例では、スーパークラス StudDetails を作成し、サブクラス Tom を使用してそれを継承します:
class StudDetails { var mark1: Int; var mark2: Int; init(stm1:Int, results stm2:Int) { mark1 = stm1; mark2 = stm2; } func show() { print("Mark1:\(self.mark1), Mark2:\(self.mark2)") } } class Tom : StudDetails { init() { super.init(stm1: 93, results: 89) } } let tom = Tom() tom.show()
上記のプログラム実行の出力結果は次のとおりです:
Mark1:93, Mark2:89
Overriding
サブクラスは、継承されたインスタンス メソッド、クラス メソッド、インスタンス属性、またはサブスクリプトを通じて実装できます。スクリプト 独自にカスタマイズした関数の場合、この動作をオーバーライドと呼びます。
override キーワードを使用して書き換えを実装できます。
スーパー クラスのメソッド、プロパティ、サブスクリプトにアクセスする
super プレフィックスを使用して、スーパー クラスのメソッド、プロパティ、またはサブスクリプトにアクセスできます。
オーバーライド | アクセスメソッド、プロパティ、添え字スクリプト |
---|---|
method | super.somemethod() |
property | super.someProperty() |
下付きスクリプト | super[someIndex ] |
メソッドとプロパティをオーバーライドする
メソッドをオーバーライドする
サブクラスでは、override キーワードを使用してスーパークラス メソッドをオーバーライドできます。
次の例では、show() メソッドを書き直しました:
class SuperClass { func show() { print("这是超类 SuperClass") } } class SubClass: SuperClass { override func show() { print("这是子类 SubClass") } } let superClass = SuperClass() superClass.show() let subClass = SubClass() subClass.show()
上記のプログラム実行の出力結果は次のとおりです:
这是超类 SuperClass 这是子类 SubClass
プロパティの書き換え
カスタマイズされたゲッター (またはセッター) を提供して、継承されたプロパティをオーバーライドできます。継承されたプロパティが保存されたプロパティであるか計算されたプロパティであるかに関係なく、プロパティ 。
サブクラスは、継承された属性が保存されるか計算されるかを知りません。継承される属性が名前と型を持つことだけを知っています。したがって、属性をオーバーライドするときは、その名前と型を書き出す必要があります。
注:
オーバーライドされたプロパティにセッターを指定する場合は、ゲッターも指定する必要があります。
オーバーライドされたバージョンのゲッターで継承されたプロパティ値を変更したくない場合は、super.someProperty を通じて継承された値を直接返すことができます。ここで、someProperty はオーバーライドするプロパティの名前です。
次の例では、スーパークラス Circle とサブクラス Rectangle を定義します。 Rectangle クラスで、属性領域を書き換えます。
class Circle { var radius = 12.5 var area: String { return "矩形半径 \(radius) " } } // 继承超类 Circle class Rectangle: Circle { var print = 7 override var area: String { return super.area + " ,但现在被重写为 \(print)" } } let rect = Rectangle() rect.radius = 25.0 rect.print = 3 print("Radius \(rect.area)")
上記のプログラムの実行の出力結果は次のとおりです。属性オブザーバーを書き換えます
プロパティ オーバーライドで継承されたプロパティのプロパティ オブザーバーを追加できます。このようにして、継承されたプロパティ値がいつ変更されたかを検出できます。
注:
継承された定数格納プロパティまたは継承された読み取り専用の計算プロパティに対してプロパティ オブザーバーを追加することはできません。Radius 矩形半径 25.0 ,但现在被重写为 3
class Circle { var radius = 12.5 var area: String { return "矩形半径为 \(radius) " } } class Rectangle: Circle { var print = 7 override var area: String { return super.area + " ,但现在被重写为 \(print)" } } let rect = Rectangle() rect.radius = 25.0 rect.print = 3 print("半径: \(rect.area)") class Square: Rectangle { override var radius: Double { didSet { print = Int(radius/5.0)+1 } } } let sq = Square() sq.radius = 100.0 print("半径: \(sq.area)")書き換えを防ぐ
final キーワードを使用して書き換えを防ぐことができます。 最後のメソッド、属性、または添え字スクリプトをオーバーライドすると、コンパイル中にエラーが報告されます。 キーワード class の前に Final 属性 (final クラス) を追加することで、クラス全体を Final としてマークできます。そうしないと、コンパイル エラーが報告されます。
半径: 矩形半径为 25.0 ,但现在被重写为 3 半径: 矩形半径为 100.0 ,但现在被重写为 21上記の例では、final キーワードが使用されており、書き換えが許可されていないため、実行するとエラーが報告されます:
final class Circle { final var radius = 12.5 var area: String { return "矩形半径为 \(radius) " } } class Rectangle: Circle { var print = 7 override var area: String { return super.area + " ,但现在被重写为 \(print)" } } let rect = Rectangle() rect.radius = 25.0 rect.print = 3 print("半径: \(rect.area)") class Square: Rectangle { override var radius: Double { didSet { print = Int(radius/5.0)+1 } } } let sq = Square() sq.radius = 100.0 print("半径: \(sq.area)")