Java 用多态类替换开关

Java 用多态类替换开关,java,polymorphism,Java,Polymorphism,我使用switch语句对存储事件类型对象的PriorityQueue进行排序 private PriorityQueue<Event> events = new PriorityQueue<Event>(); 事件就是这样生成的 Event newArrival = new Event(1) // or 2 this.events.add(newArrival); 其中整数1表示到达,而2表示完成 class Event implements Comparable

我使用switch语句对存储事件类型对象的PriorityQueue进行排序

  private PriorityQueue<Event> events = new PriorityQueue<Event>();
事件就是这样生成的

Event newArrival = new Event(1) // or 2
this.events.add(newArrival);
其中整数
1
表示
到达
,而
2
表示
完成

class Event implements Comparable<Event> {
  private int eventType;

  public Event(int type) {
    this.eventType = type;
}
下面的switch语句根据事件对象的事件类型执行某些操作

//Event is polled out and passed to simulateEvent.
public void simulateEvent(Event e) {
    switch (e.getEventType()) {
      case 1:
        Event e = new Event(2) // If event is "1", queue a new "2", done event.
        events.add(e);
        ... 
      case 2:
        ...
      default:
        System.err.printf("Unknown event type %d\n", e.getEventType());
  }
现在我的教授告诉我,我可以用多态性来实现这一点

abstract class Event implements Comparable<Event>{
}

class ArrivalEvent extends Event implements Comparable<Event>{

}

class DoneEvent extends Event implements Comparable<Event>{

}
抽象类事件实现可比较{
}
类ArrivalEvent扩展了事件实现{
}
类DoneEvent扩展事件实现{
}
到目前为止,我看到的所有多态示例都在讨论使用父类创建数组,从而减少创建单个子对象的需要


然而,我不确定我将如何实现一个类似的、多态的样式,我的模拟器可以测试的事件。考虑到事件类型是在构造函数中设置的,我如何调整代码以删除switch语句?

事件本身应该包含要在交换机中执行的代码,因此基本上

public abstract class Event {
    public abstract void execute();
}
因此,在事件处理程序中,可以简化为

public void simulateEvent(Event e) {
    e.execute();
}
具体的实现分为以下几个类:

public class ArrivalEvent implements Event {
    public void execute() {
        arrivals.add(new DoneEvent());
    }
}
作为补充说明,我将EventType更改为枚举:

public enum EventType {
     ARRIVAL, DONE;
}
这就去掉了1表示到达,2表示完成。
如果您在上述更改后仍然需要事件类型。

您可以这样做

   public interface Event extends Comparable<Event>{
       void updateEvents(PriorityQueue events);
   }

   public class ArrivalEvent implements Event{

     public void updateEvents(PriorityQueue events) {
         events.add(DoneEvent.getInstance());
     }

     public static Event getInstance() {
         return new ArrivalEvent();
     }

   }

   public class DoneEvent implements Event {

     public void updateEvents(PriorityQueue events) {
         // Whatever is needed
     }

     public static Event getInstance() {
         return new DoneEvent();
     }

   }

   public void simulateEvent(Event e) {
       e.updateEvents(events);    
   }
公共接口事件扩展{
void updateEvents(优先级队列事件);
}
公共类ArrivalEvent实现事件{
public void updateEvents(优先级队列事件){
add(DoneEvent.getInstance());
}
公共静态事件getInstance(){
returnnewarrivalvent();
}
}
公共类DoneEvent实现事件{
public void updateEvents(优先级队列事件){
//需要什么
}
公共静态事件getInstance(){
返回新的DoneEvent();
}
}
公共无效模拟事件(事件e){
e、 更新事件(事件);
}

您将在事件中添加一个抽象的
simulate()
方法,并在ArrivalEvent和DoneeEvent中以不同的方式实现它。您可以调用event.simulate()而不是simulate(event)。旁注:您应该使用枚举字段来表示
到达
完成
,而不是整数。对不起,如果我在生成新到达/完成事件之前需要知道当前事件的类型,那么这样说是真的吗,在调用特定类的execute()方法之前,我仍然需要检查n事件的类型?@carrein不确定您的意思。。。如果像我描述的那样死亡,那么您总是知道当前事件的类型,因为您在表示事件类型的特定类的代码中。在你的问题中,你只发布了你的到达事件所做的事情,所以我也这么做了。e.updateEvents(events)会根据给定的参数(即“events”)调用哪个类,arrival/DONE吗?