プログラミング応用a 第12回『継承の基礎2』12-5 protectedアクセス特性


【12-5 protectedアクセス特性】

・protectedというアクセス修飾子でアクセス指定を受けたメンバは,
  (1)そのクラスの中から
  (2)同一パッケージの中から
  (3)そのクラスの(他のパッケージの)サブクラスの中から
 しかアクセスできない。(アクセス指定をしない場合に(3)が加わった形)

この protected アクセス特性の必要性について,コンストラクタの性質を交えて説明していこう。次の例を見よ。

サンプルリスト (zipファイルなので,ダウンロードして展開し生成されたフォルダを,新規Javaプロジェクトを作成するときに読み込むこと)



さて,ではこのスーパークラスとサブクラスを別のパッケージに分けてみよう。そうすると,エラーが起こる。なぜだろうか。

List12_List13.zip
(zipファイルなので,ダウンロードして展開し生成されたフォルダを,新規Javaプロジェクトを作成するときに読み込むこと)
下図は,クリックすると説明入りの図と交互に入れ替わる。



 この例では,スーパークラス Document のコンストラクタにはアクセス特性(public とか private とか)が指定されていない。
以前学習したように,クラスのメンバに特に明示的にアクセス特性を指定しない場合は,そのメンバは パッケージアクセス特性(同じパッケージからしかアクセスできない)
となる。つまり,Document のコンストラクタはパッケージアクセス特性を持ち,他のパッケージのクラスからはアクセスできない。

サブクラス TextDocument の自動生成されたコンストラクタは,別のパッケージにあるスーパークラス Document のデフォルトコンストラクタを自動で呼ぼうとするが,
残念ながら,Document のデフォルトコンストラクタは,他のパッケージからはアクセスできないのでエラーになるのである。

この問題を解決するには,Document のデフォルトコンストラクタを public (他のパッケージのクラスからでもアクセス可能)か,protected (他のクラスからは基本的には
アクセスできないが,サブクラスからはアクセスできる)
にすると良い。上図では,protected を利用している。

● これで,メンバのアクセス特性全種が出そろった(下表)。

  privateメンバ 指定無し(デフォルトアクセス)メンバ protectedメンバ publicメンバ
同一クラス内から
同一パッケージ内のクラスから ×
別のパッケージ内のサブクラスから × ×
別のパッケージ内の(サブクラス以外の)クラスから × × ×




 このように,サブクラスがスーパークラスと異なるパッケージに配属された場合,サブクラスからスーパークラスのメンバが利用できなくなる場合がある。
つまり,スーパークラスのメソッドを定義するとき,サブクラスから利用しても構わないメソッドに関しては,public または protected 指定にしておくと良い。
もちろん,すでに学習しているとおり,フィールドは基本的に private にしておくのが望ましい。

なお,コンストラクタはたいていの場合,public にしておいた方が無難である。