java - 从父类(super class)型方法返回子类类型

标签 java generics

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/

相关文章:

java - 如何将 libsvm 模型加载到 Android 中

C# DAL 返回泛型 List<T>

java - eclipse 编译器编译 javac 不会编译的代码 - 代码看起来是合法的

Java 等效于 C++ 模板 <int val> class foo{ };

java - 从多个 JAR 动态加载类

java - JPA 加入多列

java - Maven 依赖版本不匹配问题 - 从 repo 解决依赖的过时版本

c# - 基类中的泛型可以在父类中指定吗

java - Java 中 Class<?> 和 Class<Object> 的区别

java - 为什么这个双重检查锁是用一个单独的包装类实现的?