Java 将非泛型类扩展为泛型类

Java 将非泛型类扩展为泛型类,java,list,collections,queue,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)

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

}
public类CircularFifoQueue扩展了CircularFifoBuffer{
公共布尔加法(T数据){
返回super.add(数据);
}    
}
但是,这保留了旧的“add”方法,允许添加任意类的对象。有没有办法使用继承而不是组合(这样我就不必重新实现CircularFifoBuffer的所有方法),但防止类的用户添加非t对象?

不,你不能

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

下面是一个简单的例子。要使其正常工作,您的
CircularFifoQueue
类需要有一个
add(Object)
方法

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

@Vivien的回答已经解释了为什么这样做没有意义(有关更多信息,请阅读相关文章)


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

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

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
}
公共类循环fifoqueue{
private CircularFifoBuffer buffer=新CircularFifoBuffer();
公共布尔加法(T数据){
返回缓冲区。添加(数据);
}    
//实现所需的所有其他方法
}

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

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

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
public类CircularFifoQueue扩展了CircularFifoBuffer{
私家级卡拉斯;
公开通告(klass类){
this.klass=klass;
}
@凌驾
公共布尔添加(对象数据){
T typedData=klass.cast(数据);
返回super.add(typedData);
}
公共布尔加法(T数据){
返回super.add(数据);
}            
}
...
CircularFifQueue=新的CircularFifQueue(String.class);
queue.add(“hello”);//应该有用
队列。添加(123L);//应该抛出ClassCastException

无论如何,实现一个委托其方法调用的类并不困难。任何像样的IDE都会自动为您生成。

好的,谢谢。因此,唯一的解决方案是使用组合,并重新实现所有必要的方法?看看委托模式,它在您的案例中会起作用。谢谢,这是我决定采用的解决方案。我还实现了
Queue
来访问这些方法。唯一的问题是,我希望
add(tt)
方法返回从队列末尾掉落的对象,而这在
queue
接口的范围内似乎是不可能的。目前,我刚刚创建了一个新方法
addAndRetrieve(T)
,它满足了我的需求,尽管我很想听到其他解决方案。很好!我还希望CircularFifoQueue实现队列。