Java:方法签名中类型的子类
好的。所以我尝试使用观察者模式为应用程序设置一个 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.
因为方法签名不相同。如果没有为每种类型的组件提供单独的观察者类,我似乎无法解决这个问题,是否可以使用泛型来解决这个问题?任何帮助将不胜感激。
Ok. So I'm trying to set up a GUI for an application using the observer pattern. In standard fashion; if an Observable updates it calls the update method of all its observers, passing a ComponentUpdateEvent, as follows:
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();
}
I have a number of different components, which implement Observable, in the 'model' side of the application. Each type of component has a seperate subclass of the Drawer class, which implements Observer, for rendering to a JPanel.
The problem is that I'm trying to make it so that when the update method of a Drawer subclass is called, that the updateEvent parameter passed can be a subclass of ComponentUpdateEvent.
However, obviously if I try and do this as follows:
@Override
public void update(ConsoleUpdateEvent updateEvent) throws Exception {
if (this.componentType != updateEvent.get)) {
throw new Exception("ComponentType Mismatch.");
}
else {
messages = updateEvent.getComponentState();
}
}
I get the compiler error:
The method update(ConsoleUpdateEvent) of type ConsoleDrawer must override or implement a supertype method.
Because the method signature isn't the same. I can't seem to get around this problem without having seperate observer classes for each type of component, is it possible to solve this problem with generics? Any help would be appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的接口必须声明它
抛出异常
才能解决编译器错误。原因是您不传递类类型,而是传递 Observer 接口。因此,如果一个实现 Observable 的类抛出异常,调用类将不会知道这一情况,除非接口指定它。Your interface has to declare that it
throws Exception
to solve your compiler error. The reason for this is that you don't pass a class type around, you pass the Observer interface around. So, if one class that implements Observable throws an exception, the calling class will not know about it unless the interface specifies it.在您的
Observer
界面中,您的update()
方法不会抛出异常
,并且您的ConsoleDrawer.update()
做。根据java,这2者并不相同。您可以删除
ConsoleDrawer
上的抛出异常
,或者在Observer
接口上添加异常。In your
Observer
interface, yourupdate()
method doesn'tthrow Exception
and yourConsoleDrawer.update()
does. The 2 aren't the same according to java.Either you remove
throw Exception
onConsoleDrawer
or add the exception on theObserver
interface.一般来说,Java允许你在重写方法时削弱返回值,或者加强参数。然而,在这种情况下,您试图削弱该参数。
也许泛型可以提供帮助。我必须承认我没有尝试过下面的代码,这只是凭记忆:
你可以尝试在 Observer 接口的签名中使用泛型:
或者
除此之外,我会修改 Observable 接口的签名。
In general, Java allows you to weaken the returned value when overriding a method, or strengthen the parameters. In this case, however, you are trying to weaken the parameter.
Maybe generics can help. I have to admit that I haven't tried the code below, this is just from memory:
You can try to use generics in the signature of the Observer interface:
or
In addition to that, I'd revise the signature of Observable interface.