在 Java 中,当我重写一个方法时,编译器会将任何缩小可见性的尝试标记为错误。例如:我不能将公共方法覆盖为受保护的,而我可以将受保护的方法覆盖为公共的。
我有兴趣了解此规则背后的设计决策/思考。
在 Java 中,当我重写一个方法时,编译器会将任何缩小可见性的尝试标记为错误。例如:我不能将公共方法覆盖为受保护的,而我可以将受保护的方法覆盖为公共的。
我有兴趣了解此规则背后的设计决策/思考。
子类应始终满足超类的约定。参见Liskov 替换原则。
方法的可见性是该契约的一部分。因此,在超类中公开可见的任何内容也应该在子类中公开。
考虑一个B
继承自A
. A.m()
是公开的。现在考虑这段代码:
A obj = new B();
obj.m();
应该允许这个调用吗?是的,它应该,因为它obj
是一个类型的对象A
!它也是 type 的对象B
,但使用该对象的人不一定知道。
每个类型A
的对象都必须遵守A
. B
扩展A
,因此也必须遵守该合同。
在覆盖或实现访问级别时,我们应该选择相同的访问级别或更广泛的访问级别。
private < (default) < protected < public
公众最广泛的层面。
在接口中,所有成员都是默认公共的。因此,在实施或超越时,我们必须只公开。
假设父类和子类具有覆盖公共访问修饰符的方法。
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() 功能的类可能无法访问该函数。这不是所需的行为。
因此规则是覆盖方法不应该减少覆盖方法的范围。