【问题标题】:"Overriding" a method in class with wildcards使用通配符“覆盖”类中的方法
【发布时间】:2014-05-17 06:26:01
【问题描述】:

我正在编写一个类,它将对存储在 MyObjects 列表中的参数进行耗时的计算。由于我想轻松访问 List 的许多功能,因此我决定编写它以扩展列表类型(另一种方法是将 List 作为我的类中的字段之一并重写我将要使用的所有方法,但它看起来过于复杂)。由于计算非常复杂且耗时,而结果仅取决于存储的参数(没有时间影响,没有隐藏的依赖关系等),我决定缓存结果。所以我的代码或多或少是这样的:

public class Calculator extends ArrayList<MyObject> {

   private double Result = Double.NaN; 

   public double getResult() {
        if (Double.isNaN(Result)) {
            Result = CalculateResult();
        }
        return Result;
    }
}

这样,当第一次调用方法 getResult() 时,它会计算结果并存储它,然后在后续调用中重用。

现在,列表的内容可以用各种方法修改,很多修改都应该清除缓存。为了实现这一点,通常我会写这样的东西:

public void add(MyObject newvalue) {
    super.add(newvalue);
    Result = Double.NaN;
}

但是,它不起作用,因为“super”指的是泛型 ArrayList 类,所以编译器会产生类型错误。

在我的水平上一个明显的技巧是创建一个临时类,它将实现 MyObject 的 ArrayList 并使 Calculator 扩展这个临时类:

public class MyArrayList extends ArrayList<MyObject> {
}

public class Calculator extends MyArrayList {
}

但这看起来又过于复杂了。难道没有更优雅的方法来实现这个结果吗?或者,是否有类似于 SQL 中的触发器的机制,它会在对 List 进行任何修改时强制我的类清除缓存?

【问题讨论】:

  • 不要扩展列表实现。这将污染您的 API 并永远将类连接到该特定实现。将其用作字段并在您的类上实现List 接口,然后将您需要的方法委托给用作字段的列表实现的实例。它有点冗长,但对您班级的用户来说更加灵活和清晰。
  • 非常感谢大家的及时回复。您的示例确实解决了编译问题。然而事实上,我似乎也需要重新思考代码设计背后的基本原理。

标签: java list wildcard


【解决方案1】:

方法add应该返回布尔值,所以你需要做的就是

public boolean add(MyObject newvalue) {
    boolean retVal = super.add(newvalue);
    Result = Double.NaN;
return retVal ;
}

【讨论】:

  • 这将修复编译器错误,我赞成。但是,其他关于优先组合而不是继承的观点是:将 ArrayList 作为成员变量而不是作为超类会更好。
【解决方案2】:

这是一个很好的例子,说明composition over inheritance 何时对代码设计真正有意义。当你的类只需要有一个 List 的实例时,你的类就会被不必要的操作弄得乱七八糟。这也意味着您不会严重依赖ArrayList 实现;例如,如果您的算法调用LinkedList 怎么办?

但是,如果你真的想修复你所拥有的......

首先,您收到编译器错误的原因是,就 Java 而言,您正在尝试覆盖 add 方法,但并不完全有签名权。

正确的签名被指定为boolean add(E),但您使用void add(E) 的签名覆盖它。类型不匹配,因此您不会成功覆盖,Java 也不会编译该类,如您所见。

接下来,创建更多类来完成与继承和正确覆盖ArrayList 类相同的事情不会给您带来任何好处;如果有的话,那将是更多过于复杂。

【讨论】:

    猜你喜欢
    • 2014-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    相关资源
    最近更新 更多