如何将Iterable <interface>返回类型方法重写为Iterable <! - ?扩展接口 - >返回类型方法

时间:2016-11-05 19:23:07

标签: java oop generics override decorator

我有一个我需要实现的界面。它看起来像这样:

public interface SimulationState {
    ...
    public Iterable<VehicleStatus> getVehicleStatuses();
}

我正在尝试将接口扩展为某种装饰器接口,如下所示:

public interface SimulationStateDec<V extends VehicleStatus> extends SimulationState {
    ...
    @Override
    public Iterable<V> getVehicleStatuses();
}

public interface SimulationStateDec<V extends VehicleStatus> extends SimulationState {
    ...
    @Override
    public Iterable<? extends VehicleStatus> getVehicleStatuses();
}

这是我正在实现接口的具体类:

public class WareHouseState implements SimulationState {
    ...       
    @Override
    public Iterable<VehicleStatus> getVehicleStatuses() {
    return this.vStatuses;
   }
}

我在名为 VehicleState 的类中实现了 VehicleStatus 接口,因此我可以返回已实现的 VehicleState 虽然我的具体课程中的Iterable

所以在我的项目中的一个类中,我调用了getVehicleStatuses()方法 并且我有义务将每个元素转换为 VehicleState ,如下所示:

public class Gate {
    ...
    private ArrayList<VehicleThread> vehicles;

    public Gate(WareHouse wareHouse, GatePriority priority) {
        ...
        this.vehicles = new ArrayList<>();
        wareHouseState.getVehicleStatuses().forEach(v -> vehicles.add(new VehicleThread((VehicleState) v, wareHouse)));
        sortSameTimeArrivalBy(priority);

    }
}

我知道我在这里做错了,我想知道是否允许这种实施方式。 编译器告诉我在实现的接口中更改方法,它不适用于我的应用程序必须在不同的框架上工作。

我需要返回各种实现相同接口的具体类型,而不必转换每个元素。

2 个答案:

答案 0 :(得分:1)

你不能,因为当覆盖时你只能缩小返回类型,Iterable<V>Iterable<? extends VehicleStatus>都不是Iterable<VehicleStatus>的子类型。

在Java 8中,您可以添加新方法而不覆盖并将旧方法作为默认方法实现(或在以前的版本中使用抽象类):

public interface SimulationStateDec<V extends VehicleStatus> extends SimulationState {
    ...
    Iterable<V> getVehicleStatusesDec();

    default Iterable<VehicleStatus> getVehicleStatuses() {
        return (Iterable<VehicleStatus>) getVehicleStatusesDec();
    }
}

这应该是安全的,因为Iterable<T>没有任何以T为参数的方法:它“应该”是协变的,除了Java不支持;做同样的事情,例如List是个坏主意!

答案 1 :(得分:0)

这是你应该如何使用它,因为X&lt; A&GT;不可替代X&lt; B>即使A扩展B,简单地将Iterable&lt; VehicleStatus&GT;不可替换的是Iterable&lt; V&GT;其中V扩展了VehicleStatus.Hence,这是您在覆盖

时更改方法返回类型的错误
   public class VehicleStatus{

   }

   public interface SimulationState {
      Iterable<? extends VehicleStatus> getVehicleStatuses();
   }

   public interface SimulationStateDec<V extends VehicleStatus> extends SimulationState {
     @Override
     public Iterable<V> getVehicleStatuses();
   }