在具有泛型的子类型的继承接口中覆盖方法

时间:2013-03-29 09:10:55

标签: java generics inheritance overrides

我在java中有以下层次结构:

interface ObserverA {}

interface A {
  void method1();
  addObserver(Observer o);
}

我想像这样扩展它:

interface ObserverB extends ObserverA{}

interface B extends A {
   void method2();
   addObserver(ObserverB  o);
}

这样addObserver() B方法会覆盖A中的相同方法。 由于它不起作用,B的实现需要实现addObserver()的两个版本,我不会只有一个版本。

这是否可以巧妙地完成,不需要参与A参数化:

interface A<O extends Observer> { 
    addObserver(O o);
}

欢迎Hackish解决方案!

3 个答案:

答案 0 :(得分:4)

您不能在子接口或子类中缩小方法参数类型。您只能扩展它们,因为子类型的实现必须能够履行超类型的契约。

同样,出于同样的原因,您可以缩小返回类型和异常,但不能扩大它们。

答案 1 :(得分:2)

虽然您的示例显示了不同的内容,但我想您希望获得由不同类实现的通用接口。看看这个:

public interface Observer<T> {
    void addObserver(T t);
}

public class First implements Observer<First> {
    @Override
    public void addObserver(First t) {
    }
}

public class Second implements Observer<Second> {
    @Override
    public void addObserver(Second t) {
    }
}

正如您所看到的,First和Second类都实现了相同的接口,但具有不同类型的参数。它们通过自己的方式对已实现的界面进行参数化,但不是写Observer<Frist>,而是可以编写Observer<Integer>或任何您想要的内容。

修改

考虑到您的说明,这将是您所呈现的界面层次结构中代码的通用实现。

interface ObserverA {}

interface A<T> {
    void method1();
    void addObserver(T o);
}

interface ObserverB extends ObserverA {}

interface B extends A<ObserverB> {
    void method2();
}

答案 2 :(得分:1)

怎么样 -

interface ObserverA {}

interface A {

    <T extends ObserverA> void addObserver(T o);
}

和 -

interface ObserverB extends ObserverA{}

interface B extends A{

    // do nothing, or omit this interface entirely.

}

这样您就可以将任何继承ObserverA的类型作为参数传递给addObserver方法。

如果您正在寻找一些解释,请继续阅读。

我已在第一个界面中更改了方法以使用Bounded Type Parameter。它的声明方式,只要它的类型为addObserver,它就会允许任何对象作为参数传递给ObserverA方法,或者它继承自ObserverA。由于您的ObserverB继承自ObserverA,因此您可以安全地将ObserverAObserverB类型的对象作为参数传递给此方法。

修改

从您的澄清中,您似乎应该创建两个不同的接口,它们之间没有任何层次关系。它们似乎是不相关的,因为您只想为第二种方法提供实现,同时避免使用第一种方法。因此,您应该将它们分开,而不是强迫自己从第一个接口提供方法的实现。还有一个OOP原则 - Interface Segregation Principle