【问题标题】:Java: using the constructor with parent class as type parameterJava:使用带有父类的构造函数作为类型参数
【发布时间】:2013-11-07 21:29:00
【问题描述】:

我有一个带有 TreeMap 字段和构造函数的类 Timeline:

public class Timeline{
    private TreeMap<DateTime, Schedulable> schedule;

    public Timeline(TreeMap<DateTime, Schedulable> schedule) {
            this.schedule = schedule;
    }
}

我有一个 Activity 类,它有一个 Timeline 作为字段:

public class Activity extends Schedulable implements Serializable {
    private Timeline legalTimes;

    public Activity() {
        legalTimes = new Timeline(new TreeMap<DateTime, LegalTime>());
        //error here for can't find constructor     ^^^^^
}

LegalTime 扩展 Schedulable 的地方。

要求:

  • 时间轴应允许其他人在其时间轴上安排任何 Schedulable 子类(不需要在 TreeMap 中保持一致)
  • Activity 的字段 legalTimes 应该只在其时间线上有 LegalTime

我认为这段代码应该可以工作,因为 LegalTime 是 Schedulable 的子类。我也无法添加第二个采用 TreeMap 的构造函数,因为它具有相同的擦除。

我该如何解决这个问题?

【问题讨论】:

  • 离题:作为最佳实践,请考虑在 Timeline 构造函数中制作 TreeMap 计划的防御性副本,并将副本分配给计划实例变量。

标签: java generics inheritance constructor


【解决方案1】:

一般来说,即使B 扩展了A,Type&lt;B&gt; 也不是Type&lt;A&gt;,因为Java 泛型是不变的。这意味着TreeMap&lt;DateTime, LegalTime&gt; 不是TreeMap&lt;DateTime, Schedulable&gt;,即使LegalTime 是Schedulable。

解决方案:

  • 将构造函数(和相应的实例变量)声明为TreeMap&lt;DateTime, ? extends Schedulable&gt;。

或

  • 将Timeline 设为泛型,泛型类型参数为所需的特定Schedulable:

试试:

public class Timeline<T extends Schedulable> {
    private TreeMap<DateTime, T> schedule;

    public Timeline(TreeMap<DateTime, T> schedule) {
        this.schedule = schedule;
    }
}

还有

private Timeline<LegalTime> legalTimes;

与

legalTimes = new Timeline<LegalTime>(new TreeMap<DateTime, LegalTime>());

【讨论】:

  • 这不是要求 TreeMap 中的所有东西都属于同一个 Schedulable 子类吗?我的想法是,其他一些班级可以将其用作通用时间线,这样它就可以在同一时间线上安排活动、会议或通勤,只要它们扩展了 Schedulable
猜你喜欢
  • 2018-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-29
  • 2018-02-28
  • 2011-08-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多