2015年8月20日木曜日

Javaのアクセス修飾子の使い分け

Javaではアクセス修飾子として可視性の低い順から
  • private: そのクラスからしか見えない
  • package-private(default): 何も指定しない場合。パッケージ内のクラスからしか見えない
  • protected: パッケージ内のクラスと子クラスから見える
  • public: どこからでも見える
がある。これらをどのように使い分けるか個人的な考えを纏めておく。あくまで個人的な指針で正しい考えとは限らない。

その前にアクセス修飾子のことから離れて、継承について考えを纏めてみる。
継承はなるべく使わない方が良い。継承を乱用するとちょっと機能を追加するのに新しいサブクラスを作成したりして、多くのクラスに機能が分散してしまう。
継承が無用と言うわけではない。使う場合は予め継承を前提とした設計を行い計画的に使う必要があるということ。心構えとしては「使わない」程度でちょうど良い。

継承を使う場合としては
  • フレームワークを使用する場合。AndroidでActivityを継承するなど。
に限ったほうが良い。もちろんinterfaceを実装する場合は別である。

このようにクラスは継承しないという前提。
また可視性は最低限に抑えたほうが良いという原則。
 Javaでは継承したクラスのメソッドをオーバライドする場合、またはinterfaceのメソッドを実装する場合には元の可視性より低い可視性は指定できないというルール。
以上をもとに各アクセス修飾子を検討する。

まずトップレベルのクラスまたはインターフェイスに付くアクセス修飾子はpackage-private(つまり何も指定しない)かpublicのどちらかである。
基本的にはpackage-privateで良い。 他のパッケージに見せる、つまり外部パッケージへのインターフェイスとなるクラスにのみpublicを付けるようにする。これは慎重に最低限に抑えるべきである。一度他のパッケージに公開したクラスは削除したり、メソッドを変えたりすると多大な影響を他に及ぼすため非常にやっかいなことになる。
つまりトップレベルのクラスの宣言は
class some_class {
...
}
とアクセス修飾子は付けなくて良い。

以下にクラス内のメンバに対するアクセス修飾子について考える。

private

private指定されたメンバはそのクラスからしか見えない。
クラス外に公開するメンバ以外は全てprivateを指定する。

package-private(default)

アクセス修飾子を付けないとこの可視性になる。これはパッケージ内のクラスからしか見えない。
クラス外に公開するメンバは基本的にこれにすること。
但しinterfaceを実装した場合は例外である。interfaceのメソッドは全てpublicでなければならない。Javaでは親の可視性より低い可視性は指定できないので、interfaceを実装した場合はそのメソッドはpublicとなる。
また継承した場合、package-privateより大きい可視性をもつメソッドをオーバーライドする場合も同様である。

protected

protected指定されたメンバはpackage-privateの可視性に加えてサブクラス(子クラス)からも見えるようになる。
継承を使用しないという前提に立つと、この修飾子を使用することは殆ど無い。例外としてフレームワークからの親クラスのメソッドをオーバーライドする場合、親クラスでの可視性がprotectedであった場合ぐらいである。

public

public指定されたメンバはどこからでも見える。
上述したようにinterfaceを実装した場合はそのメソッドにpublicを指定する。また親クラスのメソッドをオーバーライドする場合、親クラスでの可視性がpublicであった場合もpublicを指定する。
その他、複数のパッケージを使用するような比較的大きい規模のプログラムでは他のパッケージに対してのインターフェイスとなるメソッドにはpublicを指定する(クラス自体もpublicとする)。これは他のパッケージとの依存関係を作るので慎重に最低限に抑えるべきである。安易にpublic指定したメソッドを変更すると他のパッケージなど広範囲の影響を及ぼしてしまう。
mainメソッドは以下のようにpublicにする必要がある。
public static void main(String argv[])

0 件のコメント:

コメントを投稿