Понимание защищенного Java-модификатора

У меня есть class под названием A в пакете 1 и другой class C в пакете2. Класс C расширяет class A.

A имеет переменную экземпляра, которая объявляется следующим образом:

protected int protectedInt = 1; 

Вот код для classа A

 package package1; public class A { public int publicInt = 1; private int privateInt = 1; int defaultInt = 1; protected int protectedInt = 1; } 

И вот код для classа C:

 package package2; import package1.A; public class C extends A{ public void go(){ //remember the import statement A a = new A(); System.out.println(a.publicInt); System.out.println(a.protectedInt); } } 

Eclipse подчеркивает последнюю строку в C.go () и говорит, что «A.protectedInt» не отображается. Похоже, что это противоречит определению ключевого слова «protected», приведенному в документации о oracle.

Защищенный модификатор указывает, что к члену можно получить доступ только в своем собственном пакете (как и в пакете private) и, кроме того, подclassе его classа в другом пакете.

Что тут происходит?

Что тут происходит?

Вы неправильно поняли смысл protected . Вы можете получить доступ к защищенным членам, объявленным в A из C , но только для экземпляров C или подclassов C Информацию о защищенном доступе см. В разделе 6.6.2 JLS . В частности:

Пусть C – class, в котором объявлен защищенный член. Доступ разрешен только внутри тела подclassа S C.

Кроме того, если Id обозначает поле экземпляра или метод экземпляра, то:

  • […]

  • Если доступ осуществляется с помощью выражения доступа к полю E.Id, где E является первичным выражением или выражением вызова метода E.Id (…), где E является первичным выражением, тогда доступ разрешен только в том случае, если и только если тип E является S или подclassом S.

(Акцент мой.)

Так что этот код будет в порядке:

 C c = new C(); System.out.println(c.publicInt); System.out.println(c.protectedInt); 

Так как C наследует A , C может непосредственно использовать protected переменную A как показано ниже

 public class C extends A{ public void go(){ System.out.println(protectedInt); } } 

В соответствии с вашим кодом вы создаете экземпляр A и получаете доступ к protected переменной через этот экземпляр , что нарушает правило java. Защищенная переменная не видна вне пакета

  public void go(){ //remember the import statement A a = new A(); System.out.println(a.publicInt); System.out.println(a.protectedInt); } 

Когда вы делаете A a = new A(); и a.protectedInt вы пытаетесь получить доступ к защищенному члену A, который является незаконным в соответствии со стандартами java

Вместо этого вы можете сделать this.protectedInt напрямую.

Нет необходимости создавать экземпляр classа защиты внутри classа Protection2. Вы можете напрямую вызвать защищенную переменную без создания экземпляра classа защиты. Поскольку class Protection2 расширяет class защиты. Таким образом, переменная автоматически унаследована подclassом.

Попробуйте использовать код ниже:

 public class Protection2 extends Protection{ Protection2() {System.out.println("n_pro = " +n_pro); }} 

В том же пакете, где объявлен защищенный член, разрешен доступ:

 package package1; public class C extends A{ public void go(){ A a = new A(); System.out.println(a.protectedInt); // got printed C c = new C(); System.out.println(c.protectedInt); // got printed as well } } 

Вне пакета, в котором объявлен защищенный член, доступ разрешен только в том случае, если по коду, ответственному за реализацию этого объекта. В этом случае C отвечает за реализацию этого объекта, поэтому он может получить доступ к защищенному.

 package package2; public class C extends A{ public void go(){ A a = new A(); System.out.println(a.protectedInt); // compiler complains C c = new C(); System.out.println(c.protectedInt); // got printed } } 

Защищенные средства:

a) Этот член будет доступен для всех classов в одном пакете с помощью ссылки на объект.

b) Для другого пакета это будет доступно только внутри подclassов A say B, а используемая ссылка может быть экземпляра B или любого подclassа B.

Приведем пример:

Пусть A – родительский class в некотором пакете say com.ex1 Пусть B, C – classы в разных пакетах по com.ex2 say say com.ex2 . Кроме того, B extends A и C extends B Мы увидим, как мы можем использовать защищенное поле A внутри B (подclass A)

Код А:

 public class A { protected int a = 10; } 

Код B:

 public class B extends A { public void printUsingInheritance() { // Using this System.out.println(this.a); } public void printUsingInstantiation() { // Using instance of B B b = new B(); System.out.println(ba); // Using instance of C as C is subclass of B C c = new C(); System.out.println(ca); A a = new A(); System.out.println(aa); // Compilation error as A is not subclass of B } } 

Код C:

 public class C extends B { } 

Для защищенных статических :

Те же правила применяются, за исключением того, что в b) теперь он доступен в любом подclassе classа A по ссылке classа A. Справка

  • Метод оценки математических выражений в Java
  • Java: функция переопределения для отключения проверки сертификата SSL
  • Печать большого компонента Swing
  • Как продолжить выполнение, когда Assertion failed
  • Ошибка удаления гибернации: пакетное обновление возвращено Неожиданное количество строк
  • Hibernate: где insertable = false, updatable = false принадлежит составным созвездиям первичных ключей с участием внешних ключей?
  • Возможно ли использовать asynchronous вызов jdbc?
  • Как использовать JarOutputStream для создания JAR-файла?
  • Изменение префикса пространства имен XML по умолчанию, сгенерированного JAXWS
  • Объединение объектов JavaFX FXML
  • .gif изображение не перемещается при добавлении его в панель JTabbed
  • Давайте будем гением компьютера.