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

时间:2012-10-12 14:58:37

标签: java inheritance protected scjp

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

“一旦子类外部包继承受保护的成员,该成员(由子类继承)对子类外的任何代码都是私有的,但子类的子类除外。” / em>的

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

// 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!
    }
}

请向我澄清一下。感谢。

4 个答案:

答案 0 :(得分:5)

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

  

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

它指定在包外部,只有子类可以访问受保护的成员。此暗示您还可以访问包中的变量。它的措辞很差,但仍然是受保护的成员具有包级别的可见性以及子类级别的可见性。

另见:

答案 1 :(得分:3)

  

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

- >但是你在Neighbour包中移动了package1课,根据"Protected members can be accessed by classes in same package"

这是真的
  

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

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

答案 2 :(得分:1)

事实并非在“Sun认证Java程序员学习指南”中,而在于Java Language Specification

  

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

     

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

答案 3 :(得分:1)

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

package package1;

import package2.Child;

public class Neighbour {

    public void protectedTesting() {
        Parent neighboured = new Child();
        System.out.println(neighboured.i); // access
    }
}