オブジェクト指向プログラミングa 第9回『クラスの継承 (中編)』〜 9.protectedアクセス属性 |
【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 を利用している。
このように,サブクラスがスーパークラスと異なるパッケージに配属された場合,サブクラスからスーパークラスのメンバが利用できなくなる場合がある。
つまり,スーパークラスのメソッドを定義するとき,サブクラスから利用しても構わないメソッドに関しては,public または protected 指定にしておくと良い。
もちろん,すでに学習しているとおり,フィールドは基本的に private にしておくのが望ましい。
なお,コンストラクタはたいていの場合,public にしておいた方が無難である。