为什么不能通过不太具体的函数

时间:2018-06-05 23:50:32

标签: java oop interface

为什么我不能用Java做到这一点:

interface Context{
    void add(Integer o);
}
class Subclass implements Context{
    @Override
    public void add(Object o){...}
}

Subclass.add会不会实现Context.add,因为它添加(Object)可以执行所有add(Integer)可以吗?

这有什么好方法?

现在我正在做一种丑陋的方式:

private void actuallyAdd(Object o){...}
public void add(Object o){actuallyAdd(o);}
public void add(Integer o){actuallyAdd(o);}

编辑:这不是上述问题的重复。在给定的问题中,超类是具有更通用的“对象”作为参数的超类,而子类更具体。这不起作用,因为更具体的方法可能无法处理任何对象。在我的问题中,子类的特定性不如超类,这意味着子类总是能够处理超类所需的任何内容。

2 个答案:

答案 0 :(得分:5)

这是因为Java编译器要求覆盖方法的签名是重写方法的“子签名”。也就是说,参数的类型是相同的,或者参数类型的删除是相同的。

JLS, Section 8.4.8.1,说明如下:

  

在类C中声明或继承的实例方法m C ,覆盖在接口I中声明的另一个方法m I ,iff以下所有条件都为真:

...

  
      
  • m C 的签名是m I 签名的子签名(§8.4.2)。
  •   

Section 8.4.2

  

方法m 1 的签名是方法m 2 的签名的子签名,如果是:

     
      
  • m 2 与m 1 具有相同的签名,或

  •   
  • m 1 的签名与m 2 签名的删除(§4.6)相同。

  •   

你可以通过声明一个泛型类型参数来解决这个问题,正如另一个答案所示,虽然不清楚接口的最初目的是采用Integer还是仅采用某种特定但未知的类型。

答案 1 :(得分:2)

您可以尝试使用泛型:

interface Context<T> {
    void add(T t);
}

class Subclass implements Context<Object> {
    @Override
    public void add(Object o){...}
}