さて、今のサンプルを見たとき、どこか疑問を感じなかったでしょうか。
MyTestClassのインスタンスを作成するとき、こんなことをしていましたね?
MyTestClass* obj=[MyTestClass alloc];
obj = [obj init];
さあ、
MyTestClassの定義をよく見てみましょう。このクラスには「
alloc」も「
init」もありません。そんな名前のメソッドは定義されていないのです。一体、これらはどこから来たものなのでしょうか。
その秘密を解く鍵が「
継承」です。先にヘッダーについて説明をしたとき、「
NSObjectというものを継承している」ということを説明しました。この継承のおかげで、これらのメソッドが利用出来るようになっていたのです。
「
継承」というのは、既にあるクラスを受け継いで新しいクラスを作ることです。「受け継ぐ」というのは、つまり「そのクラスにあるすべてのものをまるごともらえる」ということです。つまり、そこにメソッドやインスタンス変数があれば、それらすべてをそのまま利用出来るようになる、ということなのです。
この
継承は、オブジェクト指向で登場するとても重要な考え方の一つです。
継承のおかげで、既にある資産(つまりクラス)を再利用して機能をどんどん拡張していけるからです。
Objective-Cには標準でたくさんの機能がクラスとして用意されていますが、それらも「このクラスを継承してこういう機能を付け足して、それを更に継承してこれを付け加えて……」というようにどんどん拡張して作られているんです。
この「継承する元になっているクラス」のことを「
スーパークラス」といいます。また継承して新たに作ったクラスを「
サブクラス」といいます。
NSObjectは、
MyObjCAppクラスのスーパークラス、そして
NSMyObjCAppクラスは
NSObjectクラスのサブクラス、というわけですね。
ルートクラスについて
「
Objective-Cで使われているすべてのクラス」は、「どのクラスを継承しているか」というスーパークラスをどんどんさかのぼって調べていくと、最後にはただ一つのクラスにたどり着きます。人類の祖先をどんどん遡っていくとアフリカの「イブ」というアウストラロピテクス人に辿りつくのと同じです(←全然違う)。
その「すべてのクラスのもとになるスーパークラス」が、「
NSObject」なのです。あらゆるクラスは、この
NSObjectから始まります。こうした「一番の源になるクラス」を「
ルートクラス」といいます。
allocも
initも、このルートクラスに用意されている機能なのです。ルートクラスに用意されているということは、すなわち「すべてのクラスで用意されている」ということになります。つまり、これらのメソッドは、どんなクラスであれ必ずあるものとして使うことができるわけです。
継承は非常に強力な機能である反面、本格的に使いこなすのはなかなか難しいものがあります。とりあえず今のところは「
NSObjectというものを
継承してクラスは作る」「だから
NSObjectにある機能はすべてのクラスで使える」――ということだけ覚えておいてください。実際に自分でクラスを
継承してさまざまなものを作るようになっていくまでは、そのぐらいわかっていれば十分でしょう。