我有一个我需要实现的界面。它看起来像这样:
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);
}
}
我知道我在这里做错了,我想知道是否允许这种实施方式。 编译器告诉我在实现的接口中更改方法,它不适用于我的应用程序必须在不同的框架上工作。
我需要返回各种实现相同接口的具体类型,而不必转换每个元素。
答案 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();
}