クラスの継承
クラスの継承
継承は、元になるクラスの機能(プロパティやメソッド)を引き継いだまま、新しい別の機能をつけたクラスを作成することができます。
今回の例として、すでに作成されている犬ロボット設計図(犬クラス)に対し、これとは別の新しい盲導犬ロボットの設計図を作ってみましょう。
基本的な機能は犬ロボットと同じで、盲導犬としての振る舞いである「人を案内する」というメソッドを追加するケースを考えてみます。
イメージとしては、犬クラス設計書をコピーして、新しく「盲導犬クラス設計書」とし、そこに機能を付け足していきます。
犬クラスをそのまま使ってしまうと、本来の犬クラスが変更されてしまいますので、継承(コピー)を行います。
継承先クラスの宣言 class 子クラス名: 親クラス名 { ~処理~ }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// 継承元の犬クラス(親クラス、スーパークラスとも) class Dog { var name = "" //名前 var type = "" //種類 var birthday = "" //誕生日 // 吠える func bark() { print("わんわん") } } //犬クラスを継承した盲導犬クラス(子クラス、サブクラスとも) class GuideDog: Dog { func guide() { //新しい機能を追加 print("どこへいきますか?") } } |
元となるクラスを親クラス/スーパークラス、継承して作られたクラスを子クラス/サブクラス、などと言います。
class 子クラス名: 親クラス名 { -- }
子クラスには、親クラス名の名前を想起できる名前を付けるのが一般的です。
例:UIButtonクラスを継承する場合「XXXButton」など。
そのアプリやサービス専用の部品を作るのであれば、アプリ名やサービス名の略称を付けるのもよい方法です。
試しにGuideDogのインスタンスを作成してみましょう。
.bark(親クラスのメソッド)も使えますし、.guide(子クラスの新しいメソッド)も使えることを確認してください。
このように継承は、開発工数の面でも、品質の面(元のクラスの内容を変更しないまま、機能を追加した新しいクラスを作ることができる)でもメリットがあります。
メソッドのオーバーライド
子クラスで、親クラスのメソッドを変更(上書き)してみましょう。
犬クラスの吠えるメソッド「わんわん」を、盲導犬クラスでは違いをつけて「きゃんきゃん」と設定してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// 犬クラス class Dog { var name = "" //名前 var type = "" //種類 var birthday = "" //誕生日 // 吠える func bark() { print("わんわん") } } //盲導犬クラス class GuideDog: Dog { func guide() { // 新しい機能を追加 print("どこへいきますか?") } override func bark() { // 親クラスにあった機能を上書き print("きゃんきゃん") } } |
override func メソッド名 { 変更後の処理内容 }
このオーバーライドしたメソッドを実行してみましょう。
1 2 3 4 |
var dog = Dog() dog.bark() //吠える var guideDog = GuideDog() guideDog.bark() // 吠える |
・Playgroundで確認する
上記、オーバーライドで丸ごとメソッドの処理を上書きしていますが、元の処理に+αで付け足したい時は、superキーワードで親クラスのメソッドを呼び出します。
1 |
super.親クラスのメソッド名 |
元の「わんわん」の処理に追加して「きゃんきゃん」という文字列を出力する処理に変更してみましょう。
1 2 3 4 5 6 7 8 9 |
<省略> // 盲導犬クラス class GuideDog: Dog { override func bark() { super.bark() // 継承元のクラスのbarkメソッドが呼び出される print("きゃんきゃん") } } |
それでは上書きした盲導犬クラスのbarkメソッドを出力してみましょう。guideDog.bark() は次のようになるはずです。
・Playgroundでの実行結果
継承はとても便利ですが、継承を何度も繰り返すとクラスの機能が把握しづらくなります。継承を行うかどうかはよく考えてからにしましょう。