16

在 Java 中,当我重写一个方法时,编译器会将任何缩小可见性的尝试标记为错误。例如:我不能将公共方法覆盖为受保护的,而我可以将受保护的方法覆盖为公共的。

我有兴趣了解此规则背后的设计决策/思考。

4

4 回答 4

26

子类应始终满足超类的约定。参见Liskov 替换原则

方法的可见性是该契约的一部分。因此,在超类中公开可见的任何内容也应该在子类中公开。

于 2012-07-14T14:56:57.897 回答
17

考虑一个B继承自A. A.m()是公开的。现在考虑这段代码:

A obj = new B();
obj.m();

应该允许这个调用吗?是的,它应该,因为它obj是一个类型的对象A!它也是 type 的对象B,但使用该对象的人不一定知道。

每个类型A的对象都必须遵守A. B扩展A,因此也必须遵守该合同。

于 2012-07-14T14:54:18.323 回答
5

在覆盖或实现访问级别时,我们应该选择相同的访问级别或更广泛的访问级别。

private < (default) < protected < public

公众最广泛的层面。

在接口中,所有成员都是默认公共的。因此,在实施或超越时,我们必须只公开。

于 2012-07-14T16:51:14.467 回答
1

假设父类和子类具有覆盖公共访问修饰符的方法。

class Parent{

public void m(){
// method implementation
}

}
class Child extends Parent{
@Override
public void m(){
//child implementation
}
}

假设有一些类正在使用这样的功能

Parent p = new Child();
p.m(); // this access is fine, because JVM calls Overriding method at run time

现在,如果我们将覆盖方法的访问权限更改为不公开的任何内容

class Child extends Parent{
@Override
void m(){
//Child implementation
}
}

现在,一些能够使用方法 m() 功能的类可能无法访问该函数。这不是所需的行为。

因此规则是覆盖方法不应该减少覆盖方法的范围

于 2018-10-06T12:19:58.137 回答