我想要一个函数来返回它从中调用的子类的实例

时间:2010-05-04 22:12:48

标签: java generics subclass

我希望在超类中定义一个函数,该函数返回用于调用该函数的子类的实例。也就是说,我说A级有功能插入。然后我创建了扩展A的子类B和C.我希望B.plugh返回一个B和C.plugh来返回C.是的,他们可以返回A,但是然后调用者必须将它强制转换为右边subtype,使用很多时很痛,或者声明接收变量属于超类型,这会失去类型安全性。

所以我试图用泛型来做这件事,写下这样的东西:

class A<T extends A>
{
  private T foo;
  public T getFoo()
  {
    return foo;
  }
}
class B extends A<B>
{
  public void calcFoo()
  {
    foo=... whatever ...
  } 
}
class C extends A<C>
{
   public void calcFoo()
  {
    foo=... whatever ...
  } 
}

这似乎有效,但看起来很难看。

首先,我在class A<T extends A>收到警告。编译器说A是通用的,我应该指定类型。我想它要我说class A<T extends A<x>。但是我会为x添加什么?我想我可能会陷入无限循环。

class B extends A<B>似乎很奇怪,但这不会引起任何抱怨,所以也许这很好。

这是正确的方法吗?还有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

class A<T extends A<T>> {

或者,我更喜欢:

class A<THIS extends A<THIS>> {

java.lang.Enum。它只需要A的客户端代码,但必须编写A<?>

注意这不会以任何方式破坏LSP,并且是好的。

或者您可以使用协变返回类型。

答案 1 :(得分:0)

从严格的OO角度来看,这是非常糟糕的事情。它违反Liskov Substitution Principle一个 - 如果B&amp; C都是A,然后B.getFoo()和C.getFoo()应该返回相同的东西 - 在这种情况下它们不会。如果调用者在调用方法时需要知道它得到了什么,那么你的继承层次很可能是错误的。