泛化的类和继承问题

Rom*_*man 1 java oop generics inheritance

我有一个父类Builder,可以使用Builder类型参数或其子类型进行生成:

class Builder<T extends Builder> {

    @SuppressWarnings("unchecked")
    T doSmth() {
        System.out.println("do smth");
        return (T)this;
    }
}
Run Code Online (Sandbox Code Playgroud)

它有一个子类 - BuilderChild:

class BuilderChild extends Builder<BuilderChild> {

    BuilderChild doSmthElse() {
        System.out.println("do smth else");
        return this;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,我可以doSmthBuilderChild实例上调用方法,它返回BuilderChild:

new BuilderChild().doSmth().doSmthElse();
Run Code Online (Sandbox Code Playgroud)

但是当我试图通过上面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(); 
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么在我生化后doSmth()开始回归?有没有办法解决它?BuilderBuilderChild

Joa*_*uer 5

问题是您使用的BuilderChild是原始类型.

这意味着它具有类型参数,但您指定它而不提供任何类型参数.

这意味着几乎所有该类型的泛型信息都将被忽略(它比这更复杂,但这是高级视图).

如果你这样写:

new BuilderChild<Object>().doSmth().doSmthElse();
Run Code Online (Sandbox Code Playgroud)

然后它编译.

另外,doSmthElse应指定为BuilderChild<T> doSmthElse().

请注意,仅支持原始类型以实现向后兼容性,不应在新代码中使用.