Java中重写方法的更宽泛的参数类型

以下代码打破了OO原则? 不是Java OO原则,而是一般的OO原则。

class GeneralArg{} class Arg extends GeneralArg{} class A{ public void test(Arg a){} } class B extends A{ @Override public void test(GeneralArg a){} } 

我认为这应该有效!

但是有一个编译错误,说B.test()不会覆盖B.test() A.test()

声明1:每个GeneralArg都不是Arg。

测试的基本定义是: test()Arg作为输入。

B的定义是: 同一个test()应该将GeneralArg作为输入。 但鉴于声明1,这是不可能的。

@Override说您正在覆盖基类的定义。

总之, B.test() A.test()B.test()不是相同的方法( different signatures ),因此不能覆盖另一个。

你在做什么不是压倒一切,而是超载。

更改参数列表时重载方法。 您在更改实现时覆盖方法。

  public class Foo { public void method1() { } public void method1(String str) { //We overload method1 } } public class Bar extends Foo { public void method1(String str) { // We override method1 here } public void method1(Number num) { // We overload method1 here } } 

注意,该注释不是强制性的,它只通知编译器您已覆盖某些方法以防止潜在的错误。

当您在子类声明方法时使用相同的[签名]覆盖它时,当您添加/删除switch参数顺序时,您会重载。 这个规则服从Java世界,因为每个非最终方法都是虚拟的,可以被覆盖。

这并不违反任何OO原则。 它只是改变了方法签名,这正是方法被识别的一件事。 因此,编译器没有意识到你的意图是扩展超级方法的参数类型。

Liskov替换原则允许您想要做的事情,Java只是不支持它。

不,它不应该!

通过使用Override注释方法,你会说它覆盖了某些内容但却没有。

在Java中,方法在编译时被解析和绑定。 这意味着检查声明的参数类型并选择一个方法。 此时,参数类型的inheritance并不重要。