アクセス制御と継承

2008年11月20日(木)
荻原 剛志

アクセサ

 オブジェクトの持つ状態にアクセスする必要がある場合、アクセス属性の設定によらず、アクセスしたい値を参照、変更するためのメソッドを用意する方法も考えられます。

 図2-1は時刻を表すクラスTimeOfDayに時間を参照、変更するメンバ関数getHourとsetHourを追加した例です。メンバhourのアクセス属性はprivateなので、外部から直接アクセスはできませんが、このようなメンバ関数を使えば値にアクセスすることができます。

 しかし、値の参照、変更のためだけにメソッドを定義するのは面倒なだと思うかもしれません。図2-2を見てください。時刻を分だけで保持する方式に変更しても、関数の定義だけ変更すればインタフェースを変えないですむことが分かります。

 このように、オブジェクトの属性値にアクセスするためのメソッドをアクセサと呼び、値を参照するためのアクセサをゲッタ(getter)、値を変更するためのアクセサをセッタ(setter)と呼びます。ここで「属性値」という言葉を使いましたが、図2-2の例のように、アクセスする対象が必ずしもインスタンス変数であるとは限りません。そのような属性があるものとして扱えるという点が重要です。アクセサは通常は言語仕様ではなく、オブジェクト指向言語における書き方の習慣です。

 JavaやObjective-Cでは、インスタンス変数のアクセス属性を指定することもできますが、アクセサを記述することが推奨されています。特にObjective-Cでは、アクセス制御の機能は実際のプログラミングでほとんど使われません。Smalltalkは外部からインスタンス変数に直接アクセスできませんので、インスタンス変数と同じ名前のアクセサを用意するという方法がよく使われます。

 アクセサを仕様として取り入れた言語もあります。例えばRubyでは、インスタンス変数を指定して、アクセサを簡単に作る方法が用意されています。

プロパティ

 アクセサに関連した、注目すべき機能を紹介します。

 図2-3はC#の簡単なクラス定義とその利用例を示したものです。クラスFruitはインスタンス変数u_priceを持っていますが、アクセス属性がprivateなのでクラスの外部からはアクセスできません。代わりに、Priceという名前でプロパティを定義します。

 プロパティは外部からアクセス可能なインスタンス変数であるかのように、値を参照したり、代入したりすることができます。参照する時にはgetに書かれた定義が、代入する時にはsetに書かれた定義が実行されます。setにあるvalueは代入される値を含む暗黙のパラメータです。利用する側からはpublic属性を持ったPriceというインスタンス変数があるのと変わらないという点に注目してください。プロパティにgetとsetを記述すると読み書きが可能になりますが、getだけ書くと読み出しのみ、setだけで書き込みのみのプロパティを定義できます。

 Objective-C 2.0でも宣言プロパティという機能を導入して、アクセサの定義と呼び出しが簡単にできるようになりました。こちらの場合も、アクセサに対応するインスタンス変数が存在する必要はありません。

 オブジェクト指向は言語やプログラミングだけではなく、要求分析や設計の段階から使われています。ソフトウエアの中でオブジェクトがどのような役割を担うかということをUMLなどの図を使って分析し、備えるべき操作と属性を早い段階から決めておく必要があります。

 属性は従来、プログラミングの段階ではインスタンス変数かアクセサを使って実装されていましたが、プロパティを利用するとインタフェースをまったく変更せずにクラス内の実装だけを簡単に変更できます。大変有用な機能であると言えるでしょう。

京都産業大学
京都産業大学コンピュータ理工学部教授。ソフトウエア開発手法、深層暗号などに関する研究を行う。オブジェクト指向とは20年以上の付き合いで、Mac OS X、iPhoneのアプリケーション開発も手がける。主な著書に「詳解 Objective-C 2.0」(ソフトバンク)。信州生まれだが関西暮らしが長い。http://www.kyoto-su.ac.jp/

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています