Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 泛化类与继承问题_Java_Oop_Generics_Inheritance - Fatal编程技术网

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; }
    [...]
尽管客户机代码可能更适合将构建器设置为非泛型