了解java的受保护的修饰符
我在package1中有一个名为A的类,在package2中有一个名为C的类。 C类扩展了A类
A有一个实例变量是这样声明的:
protected int protectedInt = 1;
这是A类的代码
package package1; public class A { public int publicInt = 1; private int privateInt = 1; int defaultInt = 1; protected int protectedInt = 1; }
这里是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”不可见。 看来这与oracle文档中给出的“protected”关键字的定义相冲突。
受保护的修饰符指定该成员只能在其自己的包内访问(与包私有一样),另外还可以在另一个包中访问该类的子类。
这里发生了什么?
这里发生了什么?
你误解了protected
的含义。 您可以从C
访问在A
声明的受保护成员,但只能访问C
或C
子类的实例。 有关受保护访问的详细信息,请参阅JLS的第6.6.2节 。 尤其是:
设C是声明受保护成员的类。 只有在C的子类S中才允许访问
另外,如果Id表示实例字段或实例方法,则:
[…]
如果通过字段访问表达式E.Id(其中E是主表达式)或通过方法调用表达式E.Id(…)(其中E是主表达式)来访问,则只有当且仅当如果E的类型是S或S的一个子类 。
(强调我的)
所以这段代码会很好:
C c = new C(); System.out.println(c.publicInt); System.out.println(c.protectedInt);
由于C
继承了A
, C
可以直接使用下面的A
的protected
变量
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
。
不需要在Protection2 Class中实例化Protection类。 您可以直接调用受保护的变量而不用实例化Protection类。 由于Protection2类扩展了Protection类。 所以变量自动被子类继承。
试试下面的代码:
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 } }