[英]“Hiding” overridden methods in Java
假设我有一些课程
public class Foo {
public void foo(int number) {
// Do some foo-ing of the given number
}
}
和另一个扩展它的类
public class FooExtension extends Foo {
public void foo(String text) {
super.foo(text.length());
}
}
让我们说如果你使用的是FooExtension
对象,你真的不应该调用foo(int number)
方法,而是只使用foo(String text)
。
由于在我将FooExtension
实例分配给Foo
变量时会破坏契约,因此无法覆盖具有较低可见性的原始类的foo(int number)
方法。
有没有一种方法被认为是“良好做法”,表明如果你使用FooExtension
,你真的不应该再调用foo
的原始版本了吗? 也许压倒它并标记它已被弃用? 或者重写它并让它抛出UnsupportedOperationException
?
有没有一种方法被认为是“良好做法”,表明如果你使用FooExtension,你真的不应该再调用原始版本的foo了吗? 也许压倒它并标记它已被弃用? 或者重写它并让它抛出UnsupportedOperationException?
当你从一个“坏习惯”开始时,很难定义一个“良好实践”。 如果你是从类继承,但是你不想要父类的某些方法,那么你根本就不应该使用继承!
可能吗? 是的,可以做你想做的事:
public class FooExtension extends Foo {
@Override
public void foo(int number) {
throw new UsupportedOperationException("Operation is not supported");
}
public void foo(String text) {
super.foo(text.length());
}
}
但我觉得设计这样的东西很糟糕。 如果他们试图调用属于超类型的方法并获得异常,则代码的用户可能会感到惊讶。
在这种情况下,使用组合而不是继承更好。 这样,你可以简单地委派只有你想要的来电,你的内部实例。
编辑
公共继承是一种“是一种”关系。 因此,从使用您的类的人的角度来看,他们会期望FooExtension
的行为类似于Foo
,除了一些额外的行为。 通过做你正在做的事情,你违反了这个定义。
您的设计违反的另一件事是Liskov替代原则 。 原理说如果你有一个类型为T
的子类型S
,那么用类型S
对象替换类型为T
的对象不应该改变你的程序的行为。
如果要遵循您的设计,用FooExtension
替换Foo
实例将导致程序失败。 这就是为什么你真正想要做的不是真的。
这不是一个覆盖。 这是一个过载。 如果重载方法在基类中,则重载会隐藏它们重载的方法。 这是Java和C ++的基本规则。
因此,您的问题的答案已经发生了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.