【问题标题】:How do I Override a Iterable<interface> return type method into Iterable<? extends interface> return type method如何将 Iterable<interface> 返回类型方法重写为 Iterable<?扩展接口>返回类型方法
【发布时间】:2017-03-19 10:38:44
【问题描述】:

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

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);

    }
}

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

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

【问题讨论】:

标签: java oop generics overriding decorator


【解决方案1】:

这就是你应该使用它的方式,因为即使 A 扩展了 B,X 也不能被 X 替代,简单地说,Iterable 不能被 Iterable 替换,其中 V 扩展了 VehicleStatus。因此,您在覆盖时更改方法返回类型的错误

   public class VehicleStatus{

   }

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

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

【讨论】:

    【解决方案2】:

    你不能,因为重写时你只能缩小返回类型,Iterable&lt;V&gt;Iterable&lt;? extends VehicleStatus&gt; 都不是Iterable&lt;VehicleStatus&gt; 的子类型。

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-10
      • 1970-01-01
      • 2014-09-08
      • 1970-01-01
      • 1970-01-01
      • 2017-05-09
      相关资源
      最近更新 更多