在Java中,当我覆盖一个方法时,编译器会将任何将可见性范围缩小的尝试标记为错误。例如:我不能将公共方法覆盖为protected,而我可以将受保护的方法覆盖为public。
我有兴趣了解这条规则背后的设计决策/思考。
答案 0 :(得分:22)
子类应始终满足超类的约定。请参阅Liskov Substitution principle。
方法的可见性是本合同的一部分。因此,超类中公开可见的任何内容也应该在子类中公开。
答案 1 :(得分:17)
考虑一个继承自B
的班级A
。 A.m()
是公开的。现在考虑这段代码:
A obj = new B();
obj.m();
是否允许此通话?是的,应该,因为obj
是A
类型的对象!它也是B
类型的对象,但使用该对象的对象不一定知道。
A
类型的每个对象都必须遵守A
的合同(接口)。 B
延长A
,因此也必须遵守该合同。
答案 2 :(得分:4)
在超越或实施访问级别时,我们应该采用相同的访问级别或更广泛的访问级别。
private < (default) < protected < public
公众是最广泛的。
在界面中,所有成员都是默认公开的。因此,在实施或超越时,我们必须只为公开。
答案 3 :(得分: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
现在,如果我们将覆盖方法的访问权限更改为除public以外的任何内容
class Child extends Parent{
@Override
void m(){
//Child implementation
}
}
现在,某些能够使用方法m()的功能的类可能无法访问该功能。这不是期望的行为。
因此规则是覆盖方法不应缩小覆盖方法的范围。