iPhone用アプリケーション開発で注目を集める言語「Objective-C」。C++とは異なるC言語の拡張を目指したこの言語の基本を理解しよう(編集部)
前回の「一番初めのObjective-Cプログラム」では、シンプルなサンプルプログラムに沿って、クラス定義の最低限のルールを解説しました。
今回からは、プログラムの構成要素の1つ1つをより深く掘り下げていきたいと思います。その手始めとして、まずはオブジェクト指向の中核であるクラスの定義方法について解説します。前回までの解説と多少重複する部分もありますが、クラスに含まれる構成要素について、より詳しく見ていくことにしましょう。
なお、今回のサンプルは、説明やファイル作成を簡単にするために、クラスの宣言、クラスの実装、およびmain関数による実行部分までを1つのファイルに記述しています。ソースファイル名を「main.m」とし、実行ファイル名を「test」とする場合、コンパイルと実行は以下のコマンドで行うことができます(コンパイルと実行の詳細については前回の記事を参照してください)。
gcc -o test main.m -framework Foundation |
コンパイルとリンク |
./test |
実行 |
すでに何度か述べたように、クラスの宣言部は@interfaceから始まるコンパイラディレクティブに、クラスの実装部は@implementationから始まるコンパイラディレクティブに、それぞれ記述します。クラス名は、「クラス名 : スーパークラス名」のように記述します。クラスの空の器だけを記述してみると、以下のようになります。
/* クラスの宣言部 */ |
「スーパークラス」は、既存のクラスから機能や属性を「継承」したい場合に指定します。特に具体的なスーパークラスの想定がなければ、通常は上記のようにNSObjectをスーパークラスとします。NSObjectは、Objective-Cのクラスに必要な多くの機能をすでに実装しているのです。クラスの継承はオブジェクト指向の非常に重要な概念ですので、別の回で詳しく説明したいと思います。
なお、「 : スーパークラス名」の部分は、宣言部(@interface)で記述されていれば、実装部(@implementation)では省略しても構いません。
そのクラスのメンバとなる変数群は、クラス宣言部の{と}で囲まれたブロック内に、以下のように記述します。
変数の型名 変数名;
例:
NSString *testString;
int testInt;
NSStringのようなクラスオブジェクト型の変数は、「*(アスタリスク)」を付けて宣言します。または、汎用的な型名である「id」型を利用して、「id testString;」のように宣言することもできます(この場合、アスタリスクは不要です)。
一般にクラスのメンバ変数は、クラスのインスタンス(実体)ごとに違った値を保持できる「インスタンス変数」と、クラスの型ごとに一意の値となる「静的変数(クラス変数)」の2種類がありますが、Objective-Cのメンバ変数は基本的にすべてインスタンス変数です。
Objective-Cのクラス定義の仕組みの中には、静的なメンバ変数という概念は含まれていません。別の方法で静的なメンバ変数を表現することはできるのですが、これは少し変わった方法になりますので別の機会に説明したいと思います。
なお、インスタンス変数は、ここでは宣言のみ行います。ここで具体的な値をセット(初期化)することはできません。インスタンス変数の値の初期化は、後述する初期化メソッドで行います。
クラスのインスタンス変数には、プログラム上でその変数に直接アクセスできる範囲というものが決められています。これは、大きく分けて「private」「protected」「public」の3つがあります(そのほかに「package」という範囲指定もありますが、Objective-Cではやや特殊な概念となるため、ここでは触れません)。
メンバ変数の有効範囲を指定したい場合は、以下のように記述します。
@private |
有効範囲がprivateとなっているメンバ変数は、その変数が宣言されているクラスの内部からしかアクセスできません。
有効範囲がprotectedの場合は、privateに加えて、そのクラスのサブクラス(そのクラスを直接または間接的なスーパークラスとしているクラス)からもアクセス可能となります。
有効範囲がpublicの場合は、文字通りどこからでもアクセスできます。
いままでの例のように特に有効範囲を指定しなかった場合は、その変数はprotectedとして定義されます。
多くの場合、インスタンス変数はデフォルトのprotected(アクセス範囲を指定しない)として定義され、変数へのアクセスは専用のメソッドを通して行うように設計されます。そうすることで、変数の値のセットや値の取得に関して常に一定の手続きを踏ませることができますし、想定外の値の書き換えを阻止することもできるわけです。
Copyright © ITmedia, Inc. All Rights Reserved.