Java言語を紹介する多くの書籍(『Javaプログラミング思想』を含む)は、protectedについて比較的簡単に紹介しており、基本的には一言だけです。すなわち:protected で修飾されたメンバーは、同じパッケージとそのサブクラスに対して可視である。この言い方は少し曖昧すぎて、しばしば皆さんに誤解を招きます。実際には、protected の可視性は次の2点にあります:
- 基底クラスの protected メンバーは、パッケージ内で可視であり、サブクラスに対しても可視である;
- サブクラスと基底クラスが同じパッケージ内にない場合、サブクラス内では、サブクラスのインスタンスは基底クラスから継承した protected メソッドにアクセスできますが、基底クラスのインスタンスの protected メソッドにはアクセスできません。
protected メソッドの可視性に関する以下のいくつかの例を通じて、protected キーワードをさらに理解できます。protected メンバーが関わる呼び出しに遭遇したとき、まずその protected メンバーがどこから来たのか、その可視性の範囲は何かを特定し、それから現在の使い方が可能かどうかを判断できます。以下の7つの例を見てください:
例 1
上の例について、まず(1)(3)を見てください。その中のf()メソッドはクラスFather1から継承されたもので、その可視性はパッケージp1およびそのサブクラスSon1とSon11です。f()メソッドを呼び出すクラスTest1が属するパッケージもp1であるため、(1)(3)はコンパイルが通ります。次に(2)(4)を見てください。その中のclone()メソッドの可視性は java.lang パッケージとそのすべてのサブクラスです。文「son1.clone();」と「son11.clone();」について、両者のclone()はクラスSon1、Son11内では可視ですが、Test1からは不可視であるため、(2)(4)はコンパイルが通りません。
例 2
(1)については、clone()メソッドはクラスMyObject2自体に由来するため、その可視性はパッケージp2およびMyObject2のサブクラスです。Test2はMyObject2のサブクラスですが、Test2内では基底クラスMyObject2のprotectedメソッドclone()にアクセスできないため、コンパイルは通りません。(2)については、Test2内でアクセスしているのは、自分自身のインスタンスが基底クラスMyObject2から継承したclone()であるため、コンパイルが通ります。
例 3
(1)については、clone()メソッドはクラスTest3に由来するため、その可視性はパッケージp33とそのサブクラスMyObject3です。(1)はまさにパッケージp33内のクラスTest3で呼び出されており、同じパッケージに属するため、コンパイルが通ります。
例 4
(1)については、clone()メソッドはクラスMyObject4に由来するため、その可視性はパッケージp4とそのサブクラス(ここではサブクラスはありません)です。しかし、クラスTest4はパッケージp44内にあるため、可視性を満たさず、コンパイルが通りません。
例 5
(1)については、clone()メソッドはクラスMyObject5に由来するため、その可視性はパッケージp5とそのサブクラス(ここではサブクラスはありません)です。クラスTest5もパッケージp5内にあるため、可視性を満たし、コンパイルが通ります。
例 6
(1)については、clone()メソッドはクラスTest6に由来するため、その可視性はパッケージp6とそのサブクラスMyObject6です。クラスTest6もパッケージp6内にあるため、可視性を満たし、コンパイルが通ります。
例 7
(1)については、clone()メソッドはクラスObjectに由来するため、このclone()メソッドの可視性はパッケージjava.langとそのサブクラスTest7です。クラスMyObject7はこの範囲内にないため、可視性を満たさず、コンパイルが通りません。
記事の出典:http://blog.csdn.net/justloveyou_/article/details/61672133