为什么在覆盖时不允许缩小方法的范围

时间:2012-07-14 14:47:56

标签: java oop inheritance

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

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

4 个答案:

答案 0 :(得分:22)

子类应始终满足超类的约定。请参阅Liskov Substitution principle

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

答案 1 :(得分:17)

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

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

是否允许此通话?是的,应该,因为objA类型的对象!它也是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()的功能的类可能无法访问该功能。这不是期望的行为。

因此规则是覆盖方法不应缩小覆盖方法的范围