且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Java:在过滤方法时替换参数的子类/子类型?

更新时间:2022-10-21 23:30:57

你不能。这不是埃菲尔。问题是你可以使用接口来调用不兼容类型的实现方法。所以协变参数是不允许的。逆变参数也是不允许的,但是更容易提供过载。允许Covariant返回类型(自1.5开始)。



您可以对接口进行参数化:

  public interface Observer< T extends ComponentEvent> {
无效更新(T事件)抛出异常;
}

或者,使用更有意义的界面:

  public interface ConsoleObserver {
void update(ConsoleEvent event)throws Exception;
}


So I asked this question before but I had a mistake in the code which most people picked up on, rather than the problem itself.

Anyway, I'm trying to override an interface method in a class. However, I want the type of the parameter in the overriding method to be a subclass of the type of the parameter as defined in the overriden method.

The interface is:

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

While the class that overrides this method is:

public class ConsoleDrawer extends Drawer {

//...

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

//...

}

ConsoleUpdateEvent is a subclass of ComponentUpdateEvent.

Now, I could just have the update() method in ConsoleDrawer take a ComponentUpdateEvent as a parameter and then cast it to a ConsoleUpdateEvent but I'm looking for a slightly more elegant solution if possible. Anyhelp would be appreciated. Thank you.

You can't. This is not Eiffel. The problem being that you could use the interface to call the implementation method with an incompatible type. So covariant parameters are not allowed. Contravariant parameters aren't allowed either, but it is easier to provide an overload. Covariant return type is allowed (since 1.5).

You could parameterise the interface:

public interface Observer<T extends ComponentEvent> {
    void update(T event) throws Exception;
}

Alternatively, use a more meaningful interface:

public interface ConsoleObserver {
    void update(ConsoleEvent event) throws Exception;
}