publicvoidgo(){ //remember the import statement Aa=newA(); System.out.println(a.publicInt); System.out.println(a.protectedInt);
} }
Eclipse подчеркивает последнюю строку в C.go() и говорит "A.protectedInt" не отображается. Похоже, что это противоречит определению ключевого слова "protected", учитывая, что в документации Oracle говорится:
Защищенный модификатор указывает, что к члену можно получить доступ только в его собственном пакете (как в случае с package-private) и, кроме того, подклассом его класса в другом пакете.
Что здесь происходит?
Переведено автоматически
Ответ 1
Что здесь происходит?
Вы неправильно поняли значение protected. Вы можете получить доступ к защищенным элементам, объявленным в A изнутри C, но только для экземпляров C или подклассов C. Смотрите раздел 6.6.2 JLS для получения подробной информации о защищенном доступе. В частности:
Пусть C будет классом, в котором объявлен защищенный член. Доступ разрешен только в теле подкласса-Ов C.
Кроме того, если Id обозначает поле экземпляра или метод экземпляра, то:
[...]
Осуществляется ли доступ с помощью выражения доступа к полю E.Id, где E - первичное выражение, или с помощью выражения вызова метода E.Id(. . .), где E является основным выражением, тогда доступ разрешен тогда и только тогда, когда тип E равен S или подклассу S.
Поскольку C наследуется A, C можно напрямую использовать protected переменную A, как показано ниже
publicclassCextendsA{
publicvoidgo(){
System.out.println(protectedInt);
} }
Согласно вашему коду, вы создаете экземпляр A и получаете доступ к protected переменной через этот экземпляр, что нарушает правило java - защищенная переменная не видна за пределами пакета
Ответ 3
Защищенный означает:
a) Этот элемент будет доступен для всех классов в одном пакете через ссылку на объект.
b) Для разных пакетов он будет доступен только внутри подклассов A, скажем B, и используемой ссылкой может быть экземпляр B или любого подкласса B.
Давайте рассмотрим пример:
Пусть A будет родительским классом в некотором пакете, скажем, com.ex1.
Пусть B и C будут классами в разных пакетах по отношению к A, скажем, com.ex2. Также, B extends A и C extends B.
Мы увидим, как мы можем использовать защищенные поля A внутри B (подкласса A).
Код A:
publicclassA { protectedinta=10; }
Код B:
publicclassBextendsA {
publicvoidprintUsingInheritance() { // Using this System.out.println(this.a); }
publicvoidprintUsingInstantiation() { // Using instance of B Bb=newB(); System.out.println(b.a);
// Using instance of C as C is a subclass of B Cc=newC(); System.out.println(c.a);
Aa=newA(); System.out.println(a.a); // Compilation error as A is not a subclass of B } }
Код C:
publicclassCextendsB {
}
Для защищенной статики:
Применяются те же правила, за исключением того, что в b) теперь он доступен в любом подклассе A по ссылке на класс A. Ссылка
Ответ 4
publicvoidgo(){ //remember the import statement Aa=newA(); System.out.println(a.publicInt); System.out.println(a.protectedInt);
}
Когда вы делаете A a = new A(); и a.protectedInt пытаетесь получить доступ к защищенному члену A, что незаконно в соответствии со стандартами Java
Вместо этого вы можете сделать this.protectedInt напрямую.