将非泛型类扩展为泛型类

时间:2011-05-19 11:19:48

标签: java list collections queue

org.apache.commons.collections.buffer包中的Java类CircularFifoBuffer是非泛型的,可以存储任何类的对象。

我想创建一个通用的版本,它只能保存T类的对象。我首先想到的是扩展CircularFifoBuffer并简单地编写一个新的'add'方法:

public class CircularFifoQueue<T> extends CircularFifoBuffer {

    public boolean add(T data) {
        return super.add(data);
    }    

}

但是,这会留下旧的“add”方法,允许添加任意类的对象。有没有办法使用继承而不是组合(这样我不必重新实现所有的CircularFifoBuffer方法)但是阻止类的用户添加非T对象?

4 个答案:

答案 0 :(得分:3)

不,你不能。

这是不可能的简单原因是多态性。如果您可以删除add(Object)方法,则会破坏CircularFifoBuffer类的多态性。

这是一个简单的例子。为了使其正常工作,您的CircularFifoQueue课程需要add(Object)方法。

CircularFifoBuffer buffer = new CircularFifoQueue<String>();
buffer.add(new Object());

答案 1 :(得分:3)

一个想法是实现自己的缓冲区,只包装原始缓冲区:

public class CircularFifoQueue<T> { 
  private CircularFifoBuffer buffer = new CircularFifoBuffer();

  public boolean add(T data) {
     return buffer.add(data);
  }    

  // implement all other methods that are needed
}

因此内部缓冲区会占用所有内容,但包装器确保只能添加​​T类型对象。问题:现在缓冲区没有实现任何接口。所以它的使用现在有点受限(如果您需要发送Buffer,则不能使用它)

答案 2 :(得分:0)

@Vivien的答案已经解释了为什么这样做没有意义(有关更多信息,请阅读Liskov substitution principle)。

但是,您可以通过定义add(Object)的自定义覆盖来解决此问题,该覆盖仅在运行时抛出异常。这不是一个非常优雅的解决方案,但如果你想快速修复,那么可能就是这样。

答案 3 :(得分:0)

您可以尝试以下方法。它不是很优雅,但它应该做的工作:

public class CircularFifoQueue<T> extends CircularFifoBuffer {
    private Class<T> klass;
    public CircularFifoQueue(Class<T> klass) {
        this.klass = klass;           
    }

    @Override
    public boolean add(Object data) {
        T typedData = klass.cast(data);
        return super.add(typedData);
    }

    public boolean add(T data) {
        return super.add(data);
    }            
}
...
CircularFifoQueue<String> queue = new CircularFifoQueue<String>(String.class);
queue.add("hello"); // should work
queue.add(123L); // should throw ClassCastException

无论如何,实现一个委托其方法调用的类并不是很难。任何体面的IDE都会为你自动生成。