6

我想从提供此受保护方法的类的子类中调用另一个实例的受保护方法。请参见以下示例:

public class Nano {

    protected void computeSize() {
    }

}

public class NanoContainer extends Nano {

    protected ArrayList<Nano> children;

}

public class SomeOtherNode extends NanoContainer {

    // {Nano} Overrides

    protected void computeSize() {
        for (Nano child: children) {
            child.computeSize();            // << computeSize() has protected access in nanolay.Nano
        }
    }

}

javac告诉我computeSize() has protected access in Nano。我看不出这是什么原因(我以为我已经在其他代码中这样做了)。我想保持这种方法受到保护,我该怎么办?

javac version "1.7.0_09"

编辑

我想提供一个精简的版本,但我没有考虑到这些类位于不同的包中的事实。

nanolay.Node
nanolay.NanoContainer
nanogui.SomeOtherNode
4

2 回答 2

15

不知道原因,但 JLS 在6.6.2 中证实了这一点。有关受保护访问的详细信息(强调我的):

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

所以:

package P2;
public class P2 {
    protected void foo() {}
}

.........

package P2A;    
class P2A extends P2.P2 {
    void bar(P2.P2 other) {
        this.foo(); // OK
        other.foo();  // ERROR
    }

    void bar2(P2A other) { 
        other.foo(); //OK
    }
}   

P2A.bar调用中this.foo()是可访问的,因为this负责实现P2other.foo()不可访问,因为other可能不是P2A. bar2另一方面有一个P2A所以这一切都很好。

现在,为什么如果它们都是相同的包,但如果它们是不同的包,则一切都可以?理由是什么?我不知道也想知道。

元评论我已经回滚了另一个用户最近的更新,因为它大大改变了答案,并且可能更适合作为顶级答案本身。

于 2013-01-18T18:11:14.667 回答
8

您可以通过子类化和覆盖来访问受保护的方法;当它们在同一个包中可用时。我会补充一些细节。您可以在此处阅读详细信息

您所拥有的示例protected clone()位于 java 中 Object 类中可用的方法的行上;您不能直接在任何对象上调用它(尽管所有对象都隐式地从 Object 类扩展)。

于 2013-01-18T17:32:30.353 回答