Многие книги, знакомящие с языком Java (включая "Thinking in Java"), дают довольно простое объяснение protected, по сути всего одно предложение:Члены, объявленные с модификатором protected, видимы текущему пакету и его подклассам. Это утверждение слишком расплывчато и часто приводит к недопониманию. На самом деле видимость protected заключается в двух моментах:
- Члены базового класса с модификатором protected видимы внутри пакета и для подклассов;
- Если подкласс и базовый класс находятся не в одном пакете, то в подклассе экземпляр подкласса может получать доступ к protected-методам, унаследованным от базового класса, но не может получать доступ к protected-методам экземпляра базового класса.
Мы можем глубже освоить ключевое слово protected с помощью следующих примеров, касающихся видимости protected-методов. Когда встречается вызов, связанный с protected-членом, сначала определите, откуда происходит этот protected-член и какова область его видимости, а затем можно судить, допустимо ли текущее использование. Рассмотрим следующие семь примеров:
Пример 1
В приведённом выше примере сначала рассмотрим (1) и (3). Метод f() наследуется от класса Father1, и его область видимости — пакет p1 и его подклассы Son1 и Son11. Поскольку пакет класса Test1, который вызывает метод f(), также 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 нельзя получить доступ к protected-методу clone() базового класса MyObject2, поэтому компиляция завершается ошибкой. Для (2), поскольку в Test2 осуществляется доступ к clone(), унаследованному от базового класса MyObject2 его собственным экземпляром, компиляция проходит.
Пример 3
Для (1) метод clone() происходит из класса Test3, поэтому его видимость — пакет p33, а его подкласс — MyObject3. И (1) вызывается именно в классе Test3 из пакета p33, то есть в том же пакете, поэтому компиляция проходит.
Пример 4
В случае (1) метод clone() наследуется из класса MyObject4, поэтому его видимость — пакет p4 и его подклассы (здесь подклассов нет). Но класс Test4 находится в пакете p44, поэтому условие видимости не выполняется, и компиляция завершается ошибкой.
Пример 5
В случае (1) метод clone() наследуется из класса MyObject5, поэтому его видимость — пакет p5 и его подклассы (здесь подклассов нет). Класс Test5 также находится в пакете p5, поэтому условие видимости выполняется, и компиляция проходит.
Пример 6
Для (1) метод clone() происходит из класса Test6, поэтому его видимость — package p6, а его подкласс — MyObject6. Класс Test6 также находится в пакете p6, поэтому условие видимости выполнено, и компиляция проходит.
Пример 7
Для (1) метод clone() происходит из класса Object, поэтому видимость этого метода clone() — package java.lang, а его подкласс — Test7. Поскольку класс MyObject7 не находится в этой области видимости, условие видимости не выполнено, и компиляция завершается ошибкой.
Источник: http://blog.csdn.net/justloveyou_/article/details/61672133