Java 以接口作为参数覆盖抽象 class 方法

Java Overriding abstract class method with an interface as param

我有这个摘要class:

public abstract class Foo{
   //some attributes

   public Foo(params){}

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

我有以下 class:

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

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

您的 class Bar 不会覆盖 insert,因为参数类型必须完全匹配。这是因为您的实现采用 InterfaceImplementation,而不是 SomeInterface.

你可以做些什么来编译:

  1. Barinsert方法中取一个SomeInterface作为参数,因为任何子class应该能够处理[=17=的任何实现],由 Foo.
  2. 指定

  1. SomeInterface中引入泛型来指定参数类型。

    public abstract class Foo<T extends SomeInterface>{
    

public abstract boolean insert(T param);

然后你可以在subclass:

中指定T是什么
public class Bar extends Foo<InterfaceImplementation>{

@Override
public boolean insert(InterfaceImplementation param){

假设我有

Foo foo = new Bar();

并尝试做

foo.insert(new OtherInterfaceImpl());

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

但是,Barinsert 的实现无法接受 OtherInterfaceImpl,因为您在此声明中特别说明了这一点

 public boolean insert(InterfaceImplementation param){

这会破坏类型安全,因此是不允许的。

您可以使用泛型,如 所示。

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

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

考虑方法

Number sum(Number a, Number b);

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

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

和"candidates"

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

对比

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

以上两个工具中哪个 API 正确?