0

根据我的理解,同一个包中的任何类都可以访问受保护的方法,但只有该类的子类才能从其他包中访问。

package Parent;

public class Parent {
    protected void display() {
    //Code here
    }

}
import Parent;

package Child;

class Child extends Parent{
    void view(Parent p1) {
        this.display(); // Success
        p1.display();  // Error
    }

    void next(Parent p2) { 
        p2.foo(); //Success
    }
}   

这里this.display()是成功的,因为子类负责实现。但p1.display()不工作,因为p1不是Child类的一部分。在从同一个包中的类访问受保护方法的情况下,我们如何证明这种行为是合理的?

4

3 回答 3

2

您的

p1.display();

有可能运行在任何包中实现的方法,具体取决于Parent您收到的确切子类。这显然违反了 背后的意图protected,即专门允许为扩展设计的类向其子级提供封装的方法。

如果允许该调用,则流氓类很容易从完全陌生的类中访问封装的方法。

于 2013-06-05T09:56:43.847 回答
1

Parent您提供的示例是使用传递给子项的实例调用该方法。规范规定,当范围受到保护时,对字段或实例方法的访问必须来自子类。请注意规范中声明的部分,access is permitted if and only if the type of the expression Q is S or a subclass of S. 在您的示例中,ExpressionName 是 p1,它是 的实例Parent,使其类型不是Child或子类,Child因此不允许访问。

令 C 为声明受保护成员的类。只有在 C 的子类 S 的主体内才允许访问。

此外,如果 Id 表示实例字段或实例方法,则:

如果通过限定名称 Q.Id 进行访问,其中 Q 是 ExpressionName,则当且仅当表达式 Q 的类型是 S 或 S 的子类时才允许访问。

如果通过字段访问表达式 E.Id(其中 E 是 Primary 表达式)或通过方法调用表达式 E.Id(. . .)(其中 E 是 Primary 表达式)进行访问,则当且仅如果 E 的类型是 S 或 S 的子类。

我想我明白了您试图提出的观点,因为Child它是 的子类Parent,当我们将 的实例传递Parent给方法时,Child我们应该能够调用其受保护的方法。规范的规则禁止这样做。

规格

于 2013-06-05T10:01:11.633 回答
1

如果你使用super.display()它会工作。原因是protected父类中的方法总是对子类可见,无论它们是否在同一个包中。当您只是说它p1.display()希望该方法是公共的,因为两个类都在不同的包中。

请阅读以下内容以获得更多了解。

在 Java 中,default、public、protected 和 private 之间的区别

于 2013-06-05T10:00:53.943 回答