我希望在超类中定义一个函数,该函数返回用于调用该函数的子类的实例。也就是说,我说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>
似乎很奇怪,但这不会引起任何抱怨,所以也许这很好。
这是正确的方法吗?还有更好的方法吗?
答案 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()应该返回相同的东西 - 在这种情况下它们不会。如果调用者在调用方法时需要知道它得到了什么,那么你的继承层次很可能是错误的。