Java使用接口作为参数覆盖抽象类方法

时间:2015-02-12 20:45:06

标签: java oop

我有这个抽象类:

public abstract class Foo{
   //some attributes

   public Foo(params){}

   public abstract SomeInterface search(Long id);
   public abstract boolean insert(SomeInterface param);
}

我有以下课程:

public class InterfaceImplementation implements SomeInterface {
  //Some code here
}

然后我创建了一个Foo实例:

public class Bar extends Foo{

  public Foo(params){
    super(params);
  }

  @Override
  public InterfaceImplementation search(Long id){
    // some code here
  }
  // The above code compiles

  @Override
  public boolean insert(InterfaceImplementation param){
    // some code specific to the InterfaceImplementation here
  }
  // This function does not compile/
}

那么,我做错了什么,我怎样才能实现我想做的事情呢?

3 个答案:

答案 0 :(得分:5)

您的班级Bar不会覆盖insert,因为参数类型必须完全匹配。这是因为您的实施需要InterfaceImplementation,而不是SomeInterface

你可以做些什么来编译它:

  1. SomeInterface的{​​{1}}方法中将Bar作为参数,因为任何子类都应该能够处理insert的任何实现,由{SomeInterface指定1}}。
  2. OR

    1. Foo中引入泛型,以指定参数类型。

      SomeInterface
    2. public abstract class Foo<T extends SomeInterface>{
      

      然后您可以指定子类中的public abstract boolean insert(T param);

      T

      public class Bar extends Foo<InterfaceImplementation>{
      

答案 1 :(得分:3)

让我说我有

Foo foo = new Bar();

并尝试做

foo.insert(new OtherInterfaceImpl());

我可以这样做,因为Foo#insert接受SomeInterfaceOtherInterfaceImpl实施SomeInterface

然而,Bar insert的实施无法接受OtherInterfaceImpl,因为您在此声明中明确说过

 public boolean insert(InterfaceImplementation param){

这会打破类型安全,因此不允许。

您可以使用rgettman显示的泛型。

答案 2 :(得分:0)

在实现超类方法时,您不能限制参数。

可以将输出限制为子类型。

考虑方法

Number sum(Number a, Number b);

可以与任意数字一起使用,例如

Number out = sum(Double.valueOf(1.23), Integer.valueOf(7));

和&#34;候选人&#34;

Double sum(Number a, Number b) {
  return a.doubleValue() + b.doubleValue()
}

VS

Number sum(Integer a, Double b) {
  return (Byte) (a.doubleValue() + b.doubleValue());
}

两个API中的哪一个实现了正确的API?