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

时间:2013-08-20 14:01:43

标签: java oop method-overriding

以下代码打破了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 个答案:

答案 0 :(得分:2)

  

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

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

B的定义是:相同的test()应该以{{1​​}}作为输入。但鉴于声明1,这是不可能的。

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

总之,GeneralArgA.test()不是相同的方法(B.test()),因此无法覆盖其他方法。

答案 1 :(得分:2)

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

Liskov Substitution Principle允许您想要做的事情,Java只是不支持这种方式。

答案 2 :(得分:2)

你所做的不是压倒性而是超载。

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

    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世界,因为每个非最终方法都是虚拟的,可以被覆盖。

答案 3 :(得分:1)

不,它不应该!

通过使用Override注释方法,您说它会覆盖某些内容,但它不会覆盖。

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