我有一个接口(称为Subject
),它具有以下方法:
public void addObserver(Observer o);
然后我有另一个扩展名为Subject
TimerSubject
的界面。此接口是Subject
的更具体版本,用于计时。它还有一些其他的方法。
还有两个相应的接口Observer
和TimerObserver
。 TimerObserver
扩展了Observer
。
当一个类实现TimerSubject
时,它必须覆盖addObserver()
接口的Subject
方法。看起来像这样:
@Override
public void addObserver(**Observer e**) {
observers.add(e);
}
问题是,我需要接受TimerObserver
而不是Observer
的方法,这将是这样的:
@Override
public void addObserver(**TimerObserver e**) {
observers.add(e);
}
这不起作用,因为参数与被覆盖的方法中的参数不同。
那么有没有办法用多态的参数覆盖一个方法?
答案 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)方法并且该方法完全不存在,那么这两个对象可能不像你想要的那样具有多态性。 :)