Я хотел бы понять, что происходит в примере ниже (где доступ к защищенному члену осуществляется извне пакета через подкласс).Java: защищенный доступ через пакеты
Я знаю, что для классов вне пакета подкласс может видеть защищенный элемент только через наследование.
Есть две упаковки: package1
и package2
.
package1
:ProtectedClass.java
package org.test.package1; public class ProtectedClass { protected void foo() { System.out.println("foo"); } }
package2
:ExtendsprotectedClass.java
package org.test.package2; import org.test.package1.ProtectedClass; public class ExtendsprotectedClass extends ProtectedClass { public void boo() { foo(); // This works, // since protected method is visible through inheritance } public static void main(String[] args) { ExtendsprotectedClass epc = new ExtendsprotectedClass(); epc.foo(); // Why is this working? // Since it is accessed through a reference, // foo() should not be visible, right? } }
package2
:UsesExtendedClass.java
package org.test.package2; public class UsesExtendedClass { public static void main(String[] args) { ExtendsprotectedClass epc = new ExtendsprotectedClass(); epc.foo(); // CompilationError: // The method foo() from the type ProtectedClass // is not visible } }
Следует понимать, что метод boo()
в ExtendsprotectedClass
может получить доступ к foo()
, так как защищенные члены могут быть доступны только через наследование.
Мой вопрос, почему метод foo()
работает хорошо, когда доступ через ссылку в main()
методы ExtendsprotectedClass
но не будет работать при доступе через epc
ссылки в UsesExtendedClass
?
@Jon Спасибо. Я понимаю, что члены класса подкласса могут получить доступ к защищенным членам (как указано в методе 'boo()'). Но было любопытно узнать, почему ему разрешено обращаться к защищенному члену через ссылку подкласса ** ТОЛЬКО ** в методах подкласса? любое обоснование этого? – JWhiz
@JWhiz: Редактирование ... –
2) Работает потому, что, поскольку к защищенному методу обращается указатель на свой класс. Это должно завершиться неудачно:
public static void ExtendsprotectedClass.main (String [] args) { ProtectedClass epc = new ExtendsprotectedClass(); // upcast
epc.foo(); // должна быть ошибка компиляции?
} –