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

Java 为什么子类可以使用其他包中类的受保护字段?,java,Java,我使用Boyarskiy OCA认证书,第173页 因此,我面临一些问题: 我有父类Bird和受保护的字段名以及其他包中的子项 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)

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

因此,我面临一些问题: 我有父
类Bird
受保护的
字段名以及其他包中的子项

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);
   }
}
所以, -
检查1
编译正常

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


-
check3
不编译。

protected
是一种表示外部世界私有,儿童公共的方式。一个家庭拥有世界不应该知道的秘密。这就是
check1
check2
编译的原因,因为孩子有访问权限。但是,对于
check3
,您试图访问的内容只有孩子/家庭成员才能访问,因此不允许您访问


有关OOP和访问控制的官方文档中有更多详细信息:

该主题在Java语言规范第6.6.2章中处理:

其中的示例是,类C(示例中的Bird)有一个受保护的成员,而S(示例中的Swan)是C的一个子类

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

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


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

Jeanne Boyarsky写了几本书。请张贴您正在使用的名称。我认为JLS将提供答案。顺便说一句,只是吹毛求疵,但没有任何东西试图“调用父字段名”-它试图访问该字段。不能调用字段,只能调用方法。我之所以提到这一点,是因为您提到了认证,如果您正在参加认证测试,了解正确的术语非常重要。@Abra Oracle认证的OCA java 8If
Swan
中的方法无法完全访问任何其他
Swan
实例中的所有字段,则无法实现
equals
(例如
返回this.name.equals(otherSwan.name)
)。我还忘了提到:JLS还提到:“有关访问受保护成员的更多信息,请参阅Alessandro Coglio在Java虚拟机中检查对受保护成员的访问,见《对象技术杂志》,2005年10月。”如果我没有错过任何东西的话,我会在Google上找到它。也许有些人更喜欢读这样的文章,而不是JLS。