2011-05-19 111 views
2

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

我想创建的这一个泛型版本,只能容纳类T的对象我首先想到的是扩展CircularFifoBuffer和简单的写一个新的“添加”方法:

public class CircularFifoQueue<T> extends CircularFifoBuffer { 

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

} 

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

回答

3

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

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的例子,你不能使用它)

+0

谢谢,这是我决定采用的解决方案。我也实施了'Queue '来访问这些方法。唯一的问题是,我希望'add(T t)'方法返回队列末尾的对象,而这似乎不可能在'Queue '接口的范围内。目前,我刚刚创建了一个新的方法'addAndRetrieve(T t)',它可以做我想做的事情,尽管我有兴趣听听其他解决方案。 – 2011-05-19 13:26:14

+0

好的!我也希望CircularFifoQueue能够实现Queue。 – Miguel 2012-09-20 20:39:45

3

不,你不能。

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

这是一个简单的例子。为了正确运行,您的CircularFifoQueue类需要有一个add(Object)方法。

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

好的,谢谢。所以唯一的解决方案是使用组合,并重新实施所有必要的方法? – 2011-05-19 11:24:16

+2

查看委托模式http://en.wikipedia.org/wiki/Delegation_pattern它适用于您的情况。 – 2011-05-19 11:27:37

0

@费雯丽的回答已经解释了为什么它并没有真正意义的做到这一点(有关详细信息,请阅读有关Liskov substitution principle)。

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

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都会为你自动生成。