java使用通配符“重写”类中的方法
我正在编写一个类,它将对存储在MyObject列表中的参数进行耗时的计算。因为我想轻松访问列表的许多特性,所以我决定编写它,扩展列表类型(另一种方法是将列表作为类中的一个字段,并重写我将要使用的所有方法,但这看起来像是过度复杂)。由于计算非常复杂和耗时,而结果完全取决于存储的参数(没有时间影响,没有隐藏的依赖项等),因此我决定缓存结果。因此,我的代码大致如下所示:
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中触发器的机制,每当对列表进行任何修改时,它都会强制我的类清除缓存
# 1 楼答案
这是一个很好的例子,说明了composition over inheritance何时对代码设计真正有意义。当您的类只需要有某种类型的
List
的实例浮动时,它就会被不必要的操作弄得乱七八糟。这还意味着您不需要严格依赖ArrayList
实现;例如,如果您的算法调用了一个LinkedList
来代替呢但是,如果你真的想修复你所拥有的
首先也是最重要的一点,您出现编译器错误的原因是,就Java而言,尝试重写
add
方法,但没有完全正确的签名正确的签名被指定为
boolean add(E)
,但您正在用void add(E)
签名覆盖它。这些类型不匹配,因此您将无法获得成功的重写,并且Java将不会编译该类,如您所见接下来,创建更多的类来完成与继承和正确重写
ArrayList
类相同的事情不会给您带来任何好处;如果有什么区别的话,它将更多地过度复杂化# 2 楼答案
方法
add
应该返回布尔值,因此您需要做的就是