覆盖具有多态参数的方法

时间:2012-04-05 05:51:18

标签: java polymorphism observer-pattern subject-observer

我有一个接口(称为Subject),它具有以下方法:

public void addObserver(Observer o);

然后我有另一个扩展名为Subject TimerSubject的界面。此接口是Subject的更具体版本,用于计时。它还有一些其他的方法。

还有两个相应的接口ObserverTimerObserverTimerObserver扩展了Observer

当一个类实现TimerSubject时,它必须覆盖addObserver()接口的Subject方法。看起来像这样:

@Override
public void addObserver(**Observer e**) {
    observers.add(e);
}

问题是,我需要接受TimerObserver而不是Observer的方法,这将是这样的:

@Override
public void addObserver(**TimerObserver e**) {
    observers.add(e);
}

这不起作用,因为参数与被覆盖的方法中的参数不同。

那么有没有办法用多态的参数覆盖一个方法?

2 个答案:

答案 0 :(得分:2)

我必须做一次这样的事情,我最终做的就是模仿它,即

interface Subject<T extends Observer> {
 public void addObserver(T e);
}

class TimerSubject implements Subject<TimerObserver> {
 // ...
 @Override
 public void addObserver(TimerObserver e)
 {
  observers.add(e);
 }
}

这使addObserver方法保持多态并静态强制执行参数类型。

这里的想法是,如果您希望Subject接口的每个具体实现者添加不同类型的Observers。所以你让Subject接口要求它。通过使用泛型类T扩展Observer,您仍然可以保证使用addObserver方法的人仅用于添加Observers,这是一个奖励。这样你就可以编写一个多态getter,比如

public T getObserver(T e);

填写任何派生类的类型。这样

Subject<?> foo = new TimerSubject();
// add observer somewhere
Observer bar = foo.getObserver();

也会静态输入检查。 (注意:我在这里处理内存,所以最后一点可能不完全正确,但肯定有一些方法可以让它像那样。)

答案 1 :(得分:1)

我想到了一些解决方案:

如果TimerSubject实现收到的参数不是TimerObserver,则可以通过抛出RuntimeException来实现public void addObserver(Observer)。你失去了对编译器强制类型的保护,但是后期绑定对于“真正的”多态是相当典型的。

或者,您的TimerSubject接口可以为新行为指定一个新方法addTimerObserver。大概你的TimerSubject扩展了一个已经有addObserver(Observer)实现的Subject;如果该实现完全不存在,您可以覆盖并抛出错误。但是如果TimerSubject真的没有用于addObserver(Observer)方法并且该方法完全不存在,那么这两个对象可能不像你想要的那样具有多态性。 :)