プログラミング応用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 にしておいた方が無難である。