Objective-Cでのメソッドとインスタンス変数の可視性.
メソッドの可視性
前回、前々回とちょこちょこ出てきている「可視性」という言葉。その名の通り、見えるかどうかという事です。
メソッドの可視性については前々回で少し書きましたが、もう少し詳しく話しておこうと思います。
プログラム中で、あるオブジェクトAへメッセージを送る場合
” [ オブジェクトA メソッド名]; ”
と書くのでした。
今、”人間”というプログラムがコンピュータクラスのオブジェクト”コンピュータA”に”起動”というメッセージを送るとします。そうすると”起動”メソッドがコンピュータAの中で実行され、”画面表示”や”セットアップ”など、その他様々なコンピュータAのメソッドが起動のために順に実行されるでしょう。
しかし、人間からすれば、それらのメソッドを知る必要がありません。コンピュータAを起動するために知っておくべきことは、ただ起動ボタンを押すというだけです。
コンピュータAからしても、セットアップや画面表示などのメソッドは、起動に関係ない場面で勝手に実行されても困ります。ですので、他のクラスからの操作を制限しておく必要があります。
Objective-Cでは外部からアクセスしても大丈夫なメソッドはヘッダーファイルのインターフェース部に記載するという通例があります。具体的には以下のように記述します。
/*.hファイル*/ @interface MySampleClass : NSObject { } -(void) method1; -(void) method2:(int)num; @end /*.mファイル*/ @implementation -(void) method1 { /*method1の処理*/ } -(void) method2:(int)num { /*method2の処理*/ } -(void) method3 { /*method3の処理*/ } @end
このように書いておくことで、ヘッダーファイルを読み込んだ時にこのクラスはmethod1とmethod2を使っていいんだなと暗示することができます。XcodeでもMySampleClassオブジェクトのメソッドを実行する際、サジェストされるのはこの method1とmethod2です。
では、method3は外部から実行できないのでしょうか。結論から言うと、Objective-Cではインターフェース部に書かれていようがいまいが、外部から呼び出すことができます。公開されていないだけで実行できてしまうのです。XcodeでもWarningは出ますがきちんと実行できます。
このようにメソッドを定義、実行するときは、公開されているかどうかを気にしながらプログラムを書く必用があるようです。
インスタンス変数の可視性
インスタンス変数とは、”人間”というクラスなら「名前」、「年齢」、「性別」といったそのオブジェクトの特徴を示す属性のことです。
これらの属性は外部から見えるものや、見えないものがあります。名前は知られてもいいけど、体重は…。と言った具合です。
これらの制限をつけるためにObjective-Cでは以下の4つの段階(ディレクティブ)を持ったコンパイラ指示子でその有効範囲を指定します。(参照)
- @private
- インスタンス変数は、それを宣言するクラス内でのみアクセスできます。サブクラスからはアクセス出来ません。同じクラスのインスタンスなら、メソッド内で「->」を用いてアクセスできます。
- @protected
- インスタンス変数は、それを宣言するクラス内および継承するクラス内でアクセスできます。同じクラスのインスタンスなら、メソッド内で「->」演算子を使ってアクセスできます。
- @public
- インスタンス変数は、どこからでもアクセスできます。
- @package
- そのクラスが定義されているフレームワークの内部実装からは @publicのようにアクセスできますが、フレームワークを外部から利用する場合は@privateと同様に制限されます。
インターフェース内での実際の宣言は以下のように書くことができます。
@interface MySampleClass : NSObject { float tall; UInt16 jobType; @private float salary; float weight; @protected int age; NSString* address; @public BOOL gender; NSString* name; UInt16 hairStyle; @protected UInt16 hobby; } @end
各コンパイラ指示子の有効範囲はその指示子が宣言されてから、次の指示子が現れる、もしくはリストが終了するまでです。ですのでこの場合、”@public”が適応されるのは”gender”、”name”、”hairStyle”です。@protectedのように数箇所に分けて記述することも可能です。また、何も指定していない”tall”と”jobType”はデフォルトで@protectedが適応されます。
このようにアクセスを制限することで、不用意な外部からのアクセスや書き換えを防ぐことができるようになり、予期せぬ動作を防ぐことができます。