Java:方法签名中类型的子类

时间:2010-12-09 17:59:43

标签: java generics subclass observer-pattern

确定。所以我正在尝试使用观察者模式为应用程序设置GUI。以标准方式;如果一个Observable更新它调用所有观察者的update方法,传递一个ComponentUpdateEvent,如下所示:

public interface Observable {
 ArrayList<Observer> observers = new ArrayList<Observer>();

 public void updateObservers();

 public void addObserver(Observer observer);

 public void removeObserver(Observer observer);
}

public interface Observer {
 public void update(ComponentUpdateEvent updateEvent);
}

public abstract class ComponentUpdateEvent {
 public abstract ComponentType getComponentType();
}

我在应用程序的“模型”端有许多不同的组件,它们实现了Observable。每种类型的组件都有一个Drawer类的单独子类,它实现了Observer,用于渲染到JPanel。

问题是我正在尝试这样做,以便在调用Drawer子类的update方法时,传递的updateEvent参数可以是ComponentUpdateEvent的子类。

然而,显然如果我尝试按以下方式执行此操作:

 @Override
 public void update(ConsoleUpdateEvent updateEvent) throws Exception {
  if (this.componentType != updateEvent.get)) {
   throw new Exception("ComponentType Mismatch.");
  }
  else {
   messages = updateEvent.getComponentState(); 
  }
 }

我收到编译错误:

The method update(ConsoleUpdateEvent) of type ConsoleDrawer must override or implement a supertype method.

因为方法签名不一样。如果没有为每种类型的组件提供单独的观察者类,我似乎无法解决这个问题,是否有可能用泛型来解决这个问题?任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:2)

您的接口必须声明它throws Exception来解决编译器错误。这样做的原因是你没有传递一个类类型,你传递了Observer接口。因此,如果一个实现Observable的类抛出异常,则除非接口指定它,否则调用类将不会知道它。

答案 1 :(得分:0)

Observer界面中,update()方法不会throw ExceptionConsoleDrawer.update()方法会throw Exception。根据java,这两个不一样。

您可以删除ConsoleDrawer上的Observer或在{{1}}界面上添加例外。

答案 2 :(得分:-1)

通常,Java允许您在覆盖方法时削弱返回值,或者增强参数。但是,在这种情况下,您试图削弱参数。

也许泛型可以提供帮助。我必须承认我没有尝试过下面的代码,这只是来自内存:

您可以尝试在Observer接口的签名中使用泛型:

public interface Observer<T>

public interface Observer<T extends ComponentUpdateEvent>

除此之外,我还修改了Observable接口的签名。

public void addObserver(Observer<T extends ComponentUpdateEvent> observer)