Contents

スイフト – 継承
クラスはメソッド、プロパティ、および機能を別のクラスから継承できます。クラスはさらにサブクラスとスーパークラスに分類できます。
- サブクラス -オブジェクト指向プログラミングにおいてサブクラス (英: subclass) とは、上位階層に位置するクラス(スーパークラス)のいくつかのプロパティ(特性)を継承する下位クラスのことである
- スーパークラス –スーパークラスとは、オブジェクト指向プログラミングにおいて、あるクラスの仕様を継承して新しいクラスを作成する際に、元となるクラスのこと。 新しいクラスのことは「サブクラス」(subclass)、「派生クラス」(derived class)、「子クラス」(child class)などと呼ぶ。
Swift 4クラスには、メソッド、プロパティ、関数、およびオーバーライドメソッドを呼び出してアクセスするスーパークラスが含まれています。また、プロパティオブザーバは、プロパティを追加し、ストアドまたは計算されたプロパティメソッドを変更するためにも使用されます。
ベースクラス
別のクラスからメソッド、プロパティ、または関数を継承しないクラスは、「基本クラス」と呼ばれます。
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 4" let mark1 = 98 let mark2 = 89 let mark3 = 76 print(stname) print(mark1) print(mark2) print(mark3)
次の結果が得られます。
Swift 4 98 89 76
クラス名StudDetailsは、ここでは基本クラスとして定義され、学生名を含むために使用され、3つのサブジェクトはmark1、mark2、mark3としてマークされます。’let’キーワードは基本クラスの値を初期化するために使われ、基本クラス値は ‘print’関数の助けを借りて遊び場に表示されます。
サブクラス
既存のクラスの新しいクラスを基にする行為は、「サブクラス」として定義されます。サブクラスは、その基本クラスのプロパティ、メソッド、および関数を継承します。サブクラスを定義するには、ベースクラス名の前に ‘:’が使用されます
class StudDetails { var mark1: Int; var mark2: Int; init(stm1:Int, results stm2:Int) { mark1 = stm1; mark2 = stm2; } func print() { print("Mark1:\(mark1), Mark2:\(mark2)") } } class display : StudDetails { init() { super.init(stm1: 93, results: 89) } } let marksobtained = display() marksobtained.print()
私たちが上記のプログラムを遊び場で実行すると、次の結果が得られます。
Mark1:93, Mark2:89
クラス「StudDetails」は、学生マークが宣言されているスーパークラスとして定義され、サブクラス ‘display’はスーパークラスからマークを継承するために使用されます。サブクラスは生徒のマークを定義し、print()メソッドを呼び出して生徒のマークを表示します。
オーバーライド
スーパークラスのインスタンスへのアクセス、メソッド、インスタンス、型のプロパティとサブスクリプトの入力サブクラスはオーバーライドの概念を提供します。’override’キーワードは、スーパークラスで宣言されたメソッドをオーバーライドするために使用されます。
スーパークラスのメソッド、プロパティ、サブスクリプトへのアクセス
‘super’キーワードは、スーパークラスで宣言されたメソッド、プロパティ、およびサブスクリプトにアクセスする接頭辞として使用されます
オーバーライド | メソッド、プロパティ、およびサブスクリプトへのアクセス |
メソッド | super.somemethod() |
プロパティ | super.someProperty() |
下付き文字 | スーパー[someIndex] |
オーバーライドするメソッド
継承されたインスタンスと型のメソッドは、サブクラスで定義されているメソッドに対して ‘override’キーワードでオーバーライドできます。print()は、スーパークラスprint()に記述されているtypeプロパティにアクセスするために、サブクラスでオーバーライドされています。また、cricket()スーパークラスの新しいインスタンスが ‘cricinstance’として作成されます。
class cricket { func print() { print("Welcome to Swift 4 Super Class") } } class tennis: cricket { override func print() { print("Welcome to Swift 4 Sub Class") } } let cricinstance = cricket() cricinstance.print() let tennisinstance = tennis() tennisinstance.print()
私たちが上記のプログラムを遊び場で実行すると、次の結果が得られます。
Welcome to Swift Super Class Welcome to Swift Sub Class
プロパティのオーバーライド
継承されたインスタンスまたはクラスのプロパティをオーバーライドして、そのプロパティに対して独自のカスタムゲッターとセッターを提供したり、プロパティオブザーバを追加して、オーバーライドプロパティで基になるプロパティ値が変更されたときを観察できるようにすることができます。
プロパティゲッターとセッターのオーバーライド
Swift 4では、保存されたプロパティでも、計算されたプロパティでも、継承されたプロパティをオーバーライドするカスタムゲッターとセッターを提供できます。サブクラスは継承されたプロパティ名と型を認識しません。したがって、ユーザーがスーパークラスで指定されているオーバーライドプロパティの名前と型をサブクラスで指定する必要があります。
これは2つの方法で行うことができます。
- プロパティをオーバーライドするためにsetterが定義されている場合、ユーザーはgetterも定義する必要があります。
- 継承されたプロパティゲッターを変更したくないときは、継承された値を構文 ‘super.someProperty’でスーパークラスに渡すだけです。
class Circle { var radius = 12.5 var area: String { return "of rectangle for \(radius) " } } class Rectangle: Circle { var print = 7 override var area: String { return super.area + " is now overridden as \(print)" } } let rect = Rectangle() rect.radius = 25.0 rect.print = 3 print("Radius \(rect.area)")
私たちが上記のプログラムを遊び場で実行すると、次の結果が得られます。
Radius of rectangle for 25.0 is now overridden as 3
プロパティオブザーバのオーバーライド
継承されたプロパティに対して新しいプロパティを追加する必要がある場合、 ‘プロパティオーバーライド’という概念がSwift 4に導入されています。これにより、継承されたプロパティ値が変更されたときにユーザーに通知されます。ただし、継承された定数格納プロパティおよび継承された読み取り専用の計算プロパティには、オーバーライドは適用されません。
class Circle { var radius = 12.5 var area: String { return "of rectangle for \(radius) " } } class Rectangle: Circle { var print = 7 override var area: String { return super.area + " is now overridden as \(print)" } } let rect = Rectangle() rect.radius = 25.0 rect.print = 3 print("Radius \(rect.area)") class Square: Rectangle { override var radius: Double { didSet { print = Int(radius/5.0)+1 } } } let sq = Square() sq.radius = 100.0 print("Radius \(sq.area)")
私たちが上記のプログラムを遊び場で実行すると、次の結果が得られます。
Radius of rectangle for 25.0 is now overridden as 3 Radius of rectangle for 100.0 is now overridden as 21
オーバーライドを防止するための最終プロパティ
ユーザーが他の人にスーパークラスのメソッド、プロパティ、またはサブスクリプトにアクセスする必要がない場合、Swift 4はオーバーライドを防ぐために ‘final’プロパティを導入します。’final’プロパティが宣言されると、サブスクリプトはスーパークラスのメソッド、プロパティ、およびその添え字をオーバーライドすることを許可しません。「スーパークラス」に「最終的な」特性を持たせる規定はありません。’final’プロパティが宣言されている場合、ユーザーはさらにサブクラスを作成するように制限されます。
final class Circle { final var radius = 12.5 var area: String { return "of rectangle for \(radius) " } } class Rectangle: Circle { var print = 7 override var area: String { return super.area + " is now overridden as \(print)" } } let rect = Rectangle() rect.radius = 25.0 rect.print = 3 print("Radius \(rect.area)") class Square: Rectangle { override var radius: Double { didSet { print = Int(radius/5.0)+1 } } } let sq = Square() sq.radius = 100.0 print("Radius \(sq.area)")
私たちが上記のプログラムを遊び場で実行すると、次の結果が得られます。
<stdin>:14:18: error: var overrides a 'final' var override var area: String { ^ <stdin>:7:9: note: overridden declaration is here var area: String { ^ <stdin>:12:11: error: inheritance from a final class 'Circle' class Rectangle: Circle { ^ <stdin>:25:14: error: var overrides a 'final' var override var radius: Double { ^ <stdin>:6:14: note: overridden declaration is here final var radius = 12.5
スーパークラスは ‘final’として宣言され、そのデータ型も ‘final’として宣言されるため、プログラムはサブクラスをさらに作成することができず、エラーをスローします。