Java 泛化类与继承问题
我有一个父类生成器,可以使用生成器类型或其子类型的参数进行泛化:Java 泛化类与继承问题,java,oop,generics,inheritance,Java,Oop,Generics,Inheritance,我有一个父类生成器,可以使用生成器类型或其子类型的参数进行泛化: class Builder<T extends Builder> { @SuppressWarnings("unchecked") T doSmth() { System.out.println("do smth"); return (T)this; } } 因此,我可以在BuilderChild实例上调用方法doSmth,它返回BuilderChild: 但
class Builder<T extends Builder> {
@SuppressWarnings("unchecked")
T doSmth() {
System.out.println("do smth");
return (T)this;
}
}
因此,我可以在BuilderChild实例上调用方法doSmth,它返回BuilderChild:
但是当我试图泛化BuilderChild时,上面的一行停止了编译
class BuilderChild<T> extends Builder<BuilderChild> {
BuilderChild doSmthElse() {
System.out.println("do smth else");
return this;
}
}
...
//Compile error, because doSmth()
//returns Builder instead of BuilderChild.
new BuilderChild().doSmth().doSmthElse();
有人能解释一下为什么doSmth在我将BuilderChild泛化之后启动了ReturnBuilder吗?有什么方法可以修复它吗?问题是您正在使用BuilderChild作为原始类型 这意味着它有类型参数,但指定它时不提供任何类型参数 这意味着几乎所有该类型的泛型信息都将被忽略,但这是高级视图 如果您改为这样写:
new BuilderChild<Object>().doSmth().doSmthElse();
然后进行编译
此外,doSmthElse应指定为BuilderChild doSmthElse
请注意,原始类型仅支持向后兼容,不应在新代码中使用。问题在于您将BuilderChild用作原始类型 这意味着它有类型参数,但指定它时不提供任何类型参数 这意味着几乎所有该类型的泛型信息都将被忽略,但这是高级视图 如果您改为这样写:
new BuilderChild<Object>().doSmth().doSmthElse();
然后进行编译
此外,doSmthElse应指定为BuilderChild doSmthElse
请注意,原始类型仅支持向后兼容,不应在新代码中使用。我建议执行以下操作:
abstract class Builder<T extends Builder> {
protected T getThis();
@SuppressWarnings("unchecked")
T doSmth() {
System.out.println("do smth");
return getThis();
}
}
class BuilderChild extends Builder<BuilderChild> {
protected T getThis() { return this; }
[...]
尽管客户机代码最好是让构建器非通用化。我建议执行以下操作:
abstract class Builder<T extends Builder> {
protected T getThis();
@SuppressWarnings("unchecked")
T doSmth() {
System.out.println("do smth");
return getThis();
}
}
class BuilderChild extends Builder<BuilderChild> {
protected T getThis() { return this; }
[...]
尽管客户机代码可能更适合将构建器设置为非泛型