为什么子类可以在其他包中使用类的受保护字段?

时间:2019-05-20 10:11:51

标签: java

我使用的是Boyarskiy OCA认证书,第173页。

因此,我面临一些问题: 我的父项class Bird的字段名称为protected,子项在其他软件包中。

package bird;

public class Bird{
    protected String name;
}

和孩子:

package swan;
import bird.Bird;

public class Swan extends Bird{
   public void check1(){
      System.out.print(name);
   }

   public void check2(){ 
      Swan swan = new Swan();
      System.out.print(swan.name);
   }

   public void check3(){
      Bird bird = new Bird();
      System.out.print(bird.name);
   }
}

所以, -check1可以编译

-check2编译,但是为什么呢? check2()是创建class的新实例,并尝试从其他包中调用父字段名称(而不是通过继承)。

-check3无法编译。

2 个答案:

答案 0 :(得分:2)

该主题在Java语言规范第6.6.2章中处理: https://docs.oracle.com/javase/specs/jls/se12/html/jls-6.html#jls-6.6.2.1

其中的示例是,类C(在您的示例中为Bird)具有受保护的成员,而S(在您的示例中为Swan)是C的子类。

”如果访问是通过(i)形式为ExpressionName.Id或TypeName.Id的合格名称,或(ii)形式为Primary.Id的字段访问表达式,则允许访问实例字段Id并且仅当限定类型为S或S的子类时。”

您的函数check2符合此定义,因为您有swan.name且swan的类型为“ S”(如果我们保留标准的名称C / S)。

所以check3必须失败,因为限定类型不是S(在您的示例中为Swan)或S的子类(在此使用的szenario中,类型为C-“ Bird”)。

答案 1 :(得分:1)

protected对外说私人,对孩子公开的一种表达方式。家庭拥有世界不应该知道的秘密的方式。这就是check1check2进行编译的原因,因为孩子可以访问。但是,对于check3,您正在尝试访问只有孩子/家人可以访问的内容,因此您是不允许的。

有关OOP和访问控制的官方文档中的更多详细信息,https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html