Swift 6.0 beta 日本語化計画 : Swift 6.0 beta
継承
クラスは別のクラスからメソッド、プロパティ、およびその他の特性を 継承 できます。1つのクラスが別のクラスから継承する場合、継承するクラスは サブクラス として知られており、継承されるクラスは、その スーパークラス として知られています。継承は、Swift では他の型からクラスを区別する基本的な動作です。
Swift のクラスは、それらのスーパークラスに属するメソッド、プロパティ、およびサブスクリプトを呼び出し、アクセスでき、それらの動作を洗練または変更するために、それらのメソッド、プロパティ、およびサブスクリプトの独自にオーバーライドするバージョンを提供できます。Swift は上書き(オーバーライド) が一致するスーパークラスの定義を持っている上書きの定義であることをチェックして正しいことを確認するのに役立ちます。
また、クラスはプロパティの値が変更された時に通知するように、継承されたプロパティにプロパティ監視者を追加することもできます。プロパティ監視者は、それが元々格納されたプロパティとしてかまたは計算されたプロパティとして定義されているかに関わりなく、任意のプロパティに追加できます。
別のクラスから継承していない全てのクラスは 基本クラス として知られています。
以下の例では、vehicle と言う基本クラスを定義しています。この基本クラスは、(Double のプロパティ型を推論して) 0.0 のデフォルト値で currentSpeed という格納されたプロパティを定義しています。currentSpeed プロパティの値は、vehicle の説明を作成するために読み取り専用の description と言う計算された String プロパティで使用されます。
Vehicle 基本クラスは makeNoise と言うメソッドも定義しています。このメソッドは、実際には基本の Vehicle インスタンスには何もしていませんが、後で Vehicle のサブクラスによってカスタマイズされます:
空の括弧が続く型の名前として書かれる、イニシャライザ構文 で、Vehicle の新しいインスタンスを作成します。
新しい Vehicle インスタンスを作成すると、vehicle の現在の速度を人間が読める記述にして印刷するために、 description プロパティにアクセスできます。
Vehicle クラスは、任意の車両 (vehicle) のための共通の特性を定義していますが、それ自体はあまり便利ではありません。それをより便利にするには、車両 (vehicle) のより具体的な種類を記述するためにそれを洗練する必要があります。
サブクラス化 は、既存のクラス上に新しいクラスを基づかせる行為です。サブクラスは、既存のクラスから特性を継承し、それをあなたは洗練することができます。また、サブクラスに新しい特性を追加する事もできます。
サブクラスがスーパークラスを持っていることを示すには、コロンで区切ってスーパークラスの名前の前にサブクラス名を書きます:
以下の例では、そのスーパークラスが Vehicle である Bicycle と言うサブクラスを定義しています。
新しい Bicycle クラスは、その currentSpeed と description プロパティとその makeNoise( )メソッドのような、Vehicle の特性を自動的にすべて得ます。
それが継承する特性に加えて、Bicycle クラスはデフォルト値で false (プロパティで Bool の型を推論) を持つ、新しい格納されたプロパティ、hasBasket を定義します。
デフォルトでは、作成する新しい Bicycle インスタンスは全てバスケットを持っていません。そのインスタンスが作成された後は、特定の Bicycle インスタンスに対して hasBasket プロパティを true に設定することができます。
また、Bicycle のインスタンスの、継承した currentSpeed プロパティを変更し、インスタンスの継承した description プロパティを照会することもできます。
サブクラスは、それ自体サブクラス化できます。次の例では、"タンデム" として知られている2人乗り自転車のための Bicycle のサブクラスを作成しています。
Tandem は、Bicycle からプロパティとメソッドをすべて継承し、順番に Vehicle からプロパティとメソッドをすべて継承します。Tandem サブクラスもデフォルト値が 0 の currentNumberOfPassengers という新しい格納されたプロパティを追加します。
Tandem のインスタンスを作成する場合は、その新しいものと継承されたプロパティのいずれかを操作でき、それが Vehicle から継承する読み取り専用の description プロパティを照会できます。
サブクラスは、インスタンスメソッド、型メソッド、インスタンスプロパティ、型プロパティ、サブスクリプトの独自のカスタム実装を提供でき、そうでなければスーパークラスからの継承を提供できます。これは、オーバーライド(上書き) として知られています。
それ以外の場合継承される特性をオーバーライドするには、override キーワードを、オーバーライドする定義の前に付けます。そうすることで、オーバーライドを提供する意向と、誤って一致する定義を提供していないことを明確にします。間違ってオーバーライドすると、予期しない動作を引き起こし、そしてコードがコンパイルされた時には、override キーワードなしにオーバーライドした場合はエラーと診断されます。
override キーワードはまた、オーバーライドするクラスのスーパークラス (またはその親の一つ) がオーバーライドのために提供したものと一致する宣言を持っているかをチェックするように Swift コンパイラに求めます。このチェックは、オーバーライドの定義が正しいことを確かめます。
メソッド、プロパティ、またはサブクラスのサブスクリプトオーバーライドを提供するときは、オーバーライドの一部として、既存のスーパークラスの実装を使用すると便利な場合があります。たとえば、その既存の実装の動作を洗練することができ、または既存の継承された変数に変更された値を格納できます。
これが適切である所には、super の接頭辞を使用してメソッド、プロパティ、またはサブスクリプトのスーパークラスバージョンにアクセスして下さい:
サブクラス内のメソッドの誂えた、または代替の実装を提供するために、継承されたインスタンスまたは型メソッドをオーバーライドできます。
以下の例では、Train と言う Vehicle の新しいサブクラスを定義しており、Vehicle から Train が継承した makeNoise( ) メソッドをオーバーライドしています。
Train の新しいインスタンスを作成し、その makeNoise( ) メソッドを呼び出すと、メソッドの Train サブクラスのバージョンが呼び出されたことがわかります。
そのプロパティに独自のカスタムゲッタとセッタを提供して、継承したインスタンスや型プロパティをオーバーライドでき、または基礎となるプロパティ値が変化した時監視するように、プロパティ監視者を追加してプロパティのオーバーライドを有効にします。
継承されたプロパティがソースで、格納されたプロパティとか、計算されたプロパティとして実装されているかどうかには関係なく、全ての 継承されたプロパティをオーバーライドする、カスタムのゲッタを(適切であれば、セッタも) 提供できます。継承されたプロパティの格納された、または計算された性質は、サブクラスによって知られておらず、継承されたプロパティは、特定の名前と型を持っていることを知っているだけです。オーバーライドするプロパティの名前と型を両方とも、オーバーライドが同じ名前と型のスーパークラスのプロパティと一致する事をコンパイラが確認できるよう常に宣言しなければなりません。
サブクラス・プロパティのオーバーライドでゲッタとセッタの両方を提供することで、読み書きできるプロパティとして継承された読み取り専用のプロパティを提示できます。ただし、読み取り専用のプロパティを、継承された読み書きできるプロパティとして提示することはできません。
以下の例では、Vehicle のサブクラスである Car と言う新しいクラスを定義しています。Car クラスは gear と言う新しい格納されたプロパティを導入し、そのデフォルトの整数値は 1 です。Car クラスはまた Vehicle から継承した description プロパティをオーバーライドし、現在の gear を含むカスタムの description (説明) を提供します:
description プロパティのオーバーライドは、Vehicle クラスの description プロパティを返す super.description を呼び出して始まります。description の Car クラスのバージョンは、現在の gear についての情報を提供するために、この説明 (description) の最後にいくつかテキストを追加します。
Car クラスのインスタンスを作成し、その gear と currentSpeed プロパティを設定すると、その description プロパティは、Car クラス内で定義されたぴったりの説明を返すのを見ることができます:
継承されたプロパティにプロパティ監視者を追加するには、プロパティのオーバーライドを使用できます。これは、そのプロパティがどのように元々実装されたかに関係なく、継承されたプロパティの値が変更された時に、通知されることを可能にします。プロパティ監視者の詳細については、プロパティ監視者 を参照してください。
以下の例では、Car のサブクラスである AutomaticCar と言う新しいクラスを定義しています。AutomaticCar クラスは、現在の速度に基づいて使用する、適切なギアを自動的に選択する、自動変速機のある車を表します。
AutomaticCar インスタンスの currentSpeed プロパティを設定するたびに、プロパティの didSet 監視者は、新しい速度に対するギアを適切に選択し、インスタンスの gear プロパティを設定します。具体的には、プロパティ監視者は、10 で割った新しい currentSpeed 値を、最も近い整数に切り捨て、1 を加えた値のギアを選択します。35.0 の速度は 4 のギアを生成します。
final とマークすることでメソッド、プロパティ、またはサブスクリプトを、オーバーライドされる事から防止することができます。メソッド、プロパティ、またはサブスクリプトの前置キーワードの前に final 修飾子を書くことでこれができます。(final var、final func、final class func、そして final subscript のように)
サブクラス内の final メソッド、プロパティ、またはサブスクリプトをオーバーライドしようとしても、コンパイル時エラーとして報告されます。拡張機能内のクラスに追加するメソッド、プロパティ、またはサブスクリプトも拡張機能の定義内で final としてマークできます。詳細は 拡張機能 を参照してください。
そのクラス定義 (final class) 内で class キーワードの前に final 修飾子を書くことで、全体のクラスを final とマークできます。サブクラスを final クラスにしようとすると、コンパイル時エラーとして報告されます。