public abstract class BaseClass<T extends BaseClass<T>> {
T method1(){
return getThis();
}
public abstract T getThis();
}
public class SubClass extends BaseClass<SubClass> {
public SubClass getThis(){
return this;
}
}
如果它只是一个继承级别,我可以执行类似上面的操作,并在调用 method1() 时获取 SubClass 的引用。
如果我有两个级别的继承怎么办
public abstract class SubClass1<T extends SubClass1<T>> extends BaseClass<SubClass1<T>> {
@Override
public SubClass1<T> getThis() {
return this;
}
}
public class SubSubClass1 extends SubClass1<SubSubClass1> {
}
我应该对 method1 和 BaseClass 进行哪些更改,以便在调用 method1 时我可以取回 SubSubClass1 类型。我不想在没有任何抑制警告的情况下这样做
最佳答案
重要的是要了解每个类型参数化类的类型参数都是它自己的。特别是,它们(参数本身)不与父类(super class)或子类共享。类型参数化子类故意与其父类(super class)共享类型参数值是很常见的,但这是另一回事。
类可以指定它们的父类(super class),但它们不能改变它们的父类(super class)自己的继承。因此,如果 SubClass1
延伸BaseClass<SubClass1<T>>
然后 BaseClass
类的类型参数 SubClass1<T>
及其每个子类是SubClass1<T>
,因为只有那个类(class)是SubClass1<T>
延伸。
BaseClass<T>
的任何具体子类必须实现其抽象方法 getThis()
,这需要这样一个类(例如 SubClass1
)来指定 BaseClass
的类型参数 T
作为可实例化类型(否则它不能提供返回值)。从层次结构的那一点开始,子类可以使用协变返回类型来缩小 getThis()
返回的类型。 , 但他们无法更改 BaseClass
SubClass1
指定的类型参数,除非它取决于 SubClass1
自己的类型参数。例如,这个编译干净:
public abstract class BaseClass<T extends BaseClass<T>> {
// ...
public abstract T getThis();
}
public abstract class SubClass1<T extends SubClass1<T>> extends BaseClass<SubClass1<T>> {
@Override
public SubClass1<T> getThis() {
return this;
}
}
public class SubSubClass1 extends SubClass1<SubSubClass1> {
@Override
public SubSubClass1 getThis() {
return this;
}
}
但这是协变返回类型的练习,而不是类型参数化,所以这也有效:
public abstract class BaseClass {
// ...
public abstract BaseClass getThis();
}
public abstract class SubClass1 extends BaseClass {
@Override
public SubClass1 getThis() {
return this;
}
}
public class SubSubClass1 extends SubClass1 {
@Override
public SubSubClass1 getThis() {
return this;
}
}
支持@HannoBinder,他首先在评论中建议了协变返回类型。
请注意,如果这里的主要思想是使用类型参数来标记 BaseClass
的哪个后代你实际上有——或者至少有一个上限——那就错了。在这种方法中,类型 BaseClass<SomeSubClass>
不比 SomeSubClass
类型更有意义或更具表现力本身。参数化版本的区别仅在于更难使用。
关于java - 从父类(super class)型方法返回子类类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30383491/