将非泛型类扩展为泛型类

发布于 2024-11-08 18:03:44 字数 460 浏览 0 评论 0原文

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 对象?

The Java class CircularFifoBuffer in the package org.apache.commons.collections.buffer is non-generic, and can store objects of any class.

I would like to create a generified version of this, that can only hold objects of class T. My first thought was to extend CircularFifoBuffer and simply write a new 'add' method:

public class CircularFifoQueue<T> extends CircularFifoBuffer {

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

}

However, this leaves the old 'add' method in place, allowing for objects of arbitrary class to be added. Is there a way around this that uses inheritance rather than composition (so that I don't have to re-implement all of CircularFifoBuffer's methods) but prevents users of the class from adding non-T objects?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

陈年往事 2024-11-15 18:03:45

一种想法是实现您自己的缓冲区,仅包装原始缓冲区:

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 ,则无法使用它)

One idea is t implement your own buffer that just wraps the original one:

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
}

So the internal buffer takes everything but the wrapper makes sure that only T type objects can be added. Problem: right now the buffer does not implement any interface. So it's usage is a bit limited right now (you can't use it if you need to send a Buffer for example)

卖梦商人 2024-11-15 18:03:45

不,你不能。

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

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

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

No, you can't.

The simple reason why this isn't possible is polymorphism. If you could remove the add(Object) method, you would break polymorphism for the CircularFifoBuffer class.

Here is a simple example. For this to work correctly, your CircularFifoQueue class needs to have a add(Object) method.

CircularFifoBuffer buffer = new CircularFifoQueue<String>();
buffer.add(new Object());
北陌 2024-11-15 18:03:45

@Vivien 的答案已经解释了为什么这样做实际上没有意义(有关更多信息,请阅读 < em>里氏替换原则)。

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

@Vivien's answer already explains why it doesn't really make sense to do this (for more information, read about the Liskov substitution principle).

However, you could hack around this by defining a custom override of add(Object) that simply throws an exception at run-time. It's not a very elegant solution, but if you want a quick fix, then this might be it.

江挽川 2024-11-15 18:03:45

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

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

You can try the following approach. It is not very elegant, but it should do the job:

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

Anyway, implementing a class that delegates its method calls is not very hard. Any decent IDE will autogenerate that for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文