6

我对受保护的标识符有一些疑问。在 K.Sierra 的 Sun Certified Java Programmer Study Guide 的第一章中,我发现了以下信息:

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

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

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

4 回答 4

5

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

对象的protected成员或构造函数可以从包的外部访问,在该包中,仅由负责实现该对象的代码声明它。

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

也可以看看:

于 2012-10-12T15:07:11.123 回答
3

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

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

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

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

于 2012-10-12T15:07:30.797 回答
1

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

package package1;

import package2.Child;

public class Neighbour {

    public void protectedTesting() {
        Parent neighboured = new Child();
        System.out.println(neighboured.i); // access
    }
}
于 2012-10-12T15:33:05.533 回答
1

真相不在“Sun Certified Java Programmer Study Guide”中,而是在Java 语言规范中

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

对象的受保护成员或构造函数可以从包外部访问,在该包中,仅由负责实现该对象的代码声明它。

于 2012-10-12T15:05:51.343 回答