ただし、スーパークラスのさらにスーパークラスが存在するというのは問題ありません。
例えば Objectクラスを継承したPersonをさらに継承したStudentを作成しそれをさらに継承するということは
可能です。
Person.h
@interface Person:Object
Student.h
@interface Student:Person
CollegeStudent.h
@interface CollegeStudent:Student
イメージとしてはこんな感じ。ちょっと中にメソッドとかをいれました。
こういう場合、スーパークラスのさらにスーパークラスにあるメソッドはサブクラスから使用可能となります。
上の図にもあるようにPersonにあるメソッドはCollegeStudentクラスをオブジェクト化して使用する分には、CollegeStudentで
実装していなくても使用することができます。前回作成した「initWithWeight:height」は継承したほかのクラスでも
使えるということになります。直接的なサブクラスでなくても使用できます。
こうしてあるクラスを継承してさらにそのクラスを継承するいったことしていった場合、スーパークラスを遡っていくと
必ずあるクラスになります。それがルートクラスといわれるものです。このクラスは基本的なオブジェクトとしてのふるまいを
定義してあるクラスとなります。よってすべてのクラスはこのルートクラスを継承していないといけません。
gccの場合、Objectクラスがこのルートクラスに当たります。
なのでその2記事でも書きましたが、特に継承するものがない場合、このObjectクラスを継承することになります。
つまりObjectクラスで定義されているものは他のクラスで使用できるということですね。
実装する際に注意する点としては、他のクラスを継承するならそのクラスが定義されているヘッダーファイルを
インポートしておかなければならないということでしょうか。
例えばColleageStudent.hファイルではStudent.hをインポートする必要があるということです。
オーバーライド
前回のコードでもでてきたオーバライドに関しても少し述べておきます。
initというのはインスタンスの初期化用のメソッドとしてObjectクラスに用意されています。
しかしPerson.mの方でもinitメソッドを用意していました。
前回述べたようにObjectクラスのinitはこのクラスから作成されたオブジェクトを初期化するもので、
PersonのinitはPersonクラスのオブジェクトを初期化するものであるため、同じinitというメッセージ式でも行われることは
異なるわけです。
イメージとしてはこんな感じでしょうか。
こういったサブクラス側でスーパークラスで実装されているメソッドを少し拡張したいというようなときに使われます。
別のメソッド名にしてもかまいませんが、initPersonとやるよりは統一されたinitとやるほうが
メソッド数が少なくて済みます。(コードが減るわけではないです)
クラスを利用する側(メッセージを送信する側ですね)からすると、あるオブジェクトに対してinitと送信すれば
初期化ができるということになっていれば、初期化の呼び出し方法をいくつも覚えておく必要がなくなります。
今回のまとめとしては
- 継承することによって既存のクラスのインスタンス変数、メソッドを引き継いだクラスを作成できる
- 継承される側がスーパークラス、親クラスといわれ、継承した側がサブクラス、子クラスといわれる
- 複数のクラスを一気に継承する(多重継承)はできないが、スーパークラスのスーパークラスが存在するのはかまわない
- スーパークラスで実装されているものは、階層関係にあるサブクラスであれば使用可能である
- すべてのクラスはルートクラスが基となっている
- 実装の際はスーパークラスを定義しているヘッダーファイルをインポートする必要がある
- オーバーライドという処理の上書き機能により既存のメソッドを拡張できる
- メソッドがオーバライドされていれば、その上書きされた方の処理が呼び出され、オーバライドされていなければ
スーパークラスの処理が呼び出される
といったところでしょうか。
TechProjin 開発系基礎講座 連載リンク
基礎からPHPWEBアプリ解発を学ぶなら・・
PHP基礎 連載
AIなどで注目急上昇!これから学ぶならPython!!
独学で学ぶ-pythonプログラミング 連載
汎用性◎ 定番プログラミング言語JAVA
Java基礎講座 連載