受保护的成员行为一旦被inheritance。

我对保护标识符有一些疑问。 在K.Sierra的Sun认证Java程序员学习指南的第一章中,我发现了以下信息:

“一旦子类 – 外包inheritance受保护的成员,该成员(由子类inheritance)对子类外的任何代码都是私有的,除了子类的子类。”

我提供了反映上述陈述的示例代码,这对我来说是绝对清楚的。

// Parent class package package1; import package2.Child; public class Parent { protected int i = 5; } // Child class package package2; import package1.Parent; public class Child extends Parent { // variable 'i' inherited } package package2; public class Neighbour { public void protectedTesting(){ Child child = new Child(); System.out.println(child.i); // no access } } 

我已经开始尝试并进行了一些小改动 – 将Neighbor移到package1。 并且可以访问“i”变量,这对我来说有点令人惊讶,因为它不符合语句“对子类之外的任何代码变为私有”

更改后的邻居类:

 package package1; import package2.Child; public class Neighbour { public void protectedTesting(){ Child child = new Child(); System.out.println(child.i); // access! } } 

请向我澄清一下。 谢谢。

简而言之, protected是包私有的,也是子类可见的。 甚至JLS对此也含糊不清( JLS§6.6.2 ):

protected成员或对象的构造函数可以从包外部访问,只能通过负责实现该对象的代码来声明它。

它指定在包外部,只有子类可以访问受保护的成员。 这意味着您还可以访问包中的变量。 它的措辞很差,但是真正的受保护成员具有包级别可见性以及子类级别可见性。

也可以看看:

  • 这个相关的问题
  • 用于访问控制的Java Trail

并且可以访问“i”变量,这对我来说有点令人惊讶,因为它不符合语句“对子类之外的任何代码变为私有”

– >但你在包package1移动了类Neighbour ,根据"Protected members can be accessed by classes in same package" ,这是真的

“一旦子类 – 外包inheritance受保护的成员,该成员(由子类inheritance)对子类外的任何代码都是私有的,除了子类的子类。”

– >在包内,它仍然受到保护,对于包中的所有类都不是私有的。

事实并非在“Sun认证的Java程序员学习指南”中,而在于Java语言规范

6.6.2。 受保护访问的详细信息

受保护的成员或对象的构造函数可以从包外部访问,只能通过负责实现该对象的代码来声明它。

protected visibility包括包级别可见性。 inheritance允许您将Child对象视为Parent的实例。 由于Parent的成员i在同一个包中声明,因此可以从Neighbour访问它。

 package package1; import package2.Child; public class Neighbour { public void protectedTesting() { Parent neighboured = new Child(); System.out.println(neighboured.i); // access } }