"重写"带有通配符的类中的方法

时间:2014-05-17 06:26:02

标签: java list wildcard

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

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

然而,它不起作用,因为&#34;超级&#34;指的是通用的ArrayList类,因此编译器会产生类型错误。

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

public class MyArrayList extends ArrayList<MyObject> {
}

public class Calculator extends MyArrayList {
}

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

2 个答案:

答案 0 :(得分:3)

方法add应返回布尔值,因此您需要做的就是

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

答案 1 :(得分:1)

这是一个很好的例子,说明composition over inheritance何时对代码设计有意义。当你的班级真的需要有一个List的实例漂浮在周围时,你的课将变得混乱不必要的操作。这也意味着你不依赖ArrayList实施;例如,如果您的算法需要LinkedList,那该怎么办?

但是,如果你真的想要解决你的问题......

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

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

接下来,创建更多的类来完成与继承和正确覆盖ArrayList类相同的事情将不会获得任何东西;如果有的话,它将是更多的过度复制。