3

以下代码破坏了什么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()不会覆盖A.test()

4

4 回答 4

3

您正在做的不是压倒一切,而是重载。

更改参数列表时重载方法。当你改变它的实现时,你会覆盖一个方法。

    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 
       }
  }

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

当您在子类中声明具有相同 [signature] 的方法时,您会得出结论,当您添加/删除 switch 参数顺序时,您会重载。该规则遵循 Java 世界,因为每个非最终方法都是虚拟的,并且可以被覆盖。

于 2013-08-20T14:11:32.703 回答
2

陈述 1:每个 GeneralArg 都不是 Arg。

测试的基本定义说:test()将一个Arg作为输入。

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

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

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

于 2013-08-20T14:05:55.793 回答
2

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

Liskov 替换原则允许您做任何事情,Java 只是不支持这种方式。

于 2013-08-20T14:09:48.417 回答
1

不,不应该!

通过用你注释方法Override说它覆盖了一些东西,但它没有。

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

于 2013-08-20T14:06:27.397 回答