Java泛型类型,要么是继承自某个类,要么是父类。

5
我正在寻找类似以下的代码:
```html

我正在寻找类似以下的代码:

```
public class Parent<T is_or_extends Parent<T>> {
    public T function() {
        // do some stuff //
        return correct();
    }
    public T correct() {
        return (T) this;
    }
}

这样做是为了让任何子类都可以访问其他父类函数,但仍然保持独立的类(不需要将function()的返回值向上转换为Parent实例)。 程序员也可以独立使用Parent类(因此可以创建Parent实例,而不需要将function()的返回对象向下转换)

实现:

public class Child extends Parent<Child> {}

使用方法:

Child child = new Child(); // ok
Parent<Child> polymorph = new Child(); // ok
Parent<Parent> parent = new Parent<Parent>(); // ERROR!

仅仅为了概述一个区别,这不是方法链的问题。而是当父类接收一个子类的泛型时,它不能再像上面的代码一样作为一个独立的类使用,因为用 "extends" 替换 "is_or_extends" 后,"new Parent<Parent>()" 将无法编译。
我的目标:
我想要实现的是一个父类,在被扩展时,function() 将返回一个子类的对象,而不是父类的对象。
我会使用一个泛型类型来告诉父类哪个子类调用了该函数,但是如果没有经历异常,我将无法再使用父类本身的对象。下面是一个例子:
public static class Parent<T extends Parent<T>> {}
public static class Child extends Parent<Child> {}

public static void main(String[] args) {
    // This will not compile as Parent cannot extend Parent
    Parent<Parent> parent = new Parent<Parent>();

    // This will work as Child extends Parent
    Child child = new Child();
}

预先感谢您。


我所说的Parent<Parent>是指泛型类型在函数中提供给父类有关返回哪个子类对象的信息。 - Shuba
当使用 "Parent<Child>" 时,Parent 中的方法 "function()"(在开头使用)将返回一个 Child 对象。 - Shuba
1
尝试使用Parent<?> parent = new Parent<>(); - shmosel
记录一下,extends确实意味着“是或扩展”。你的示例无法编译的原因是内部的Parent是一个原始类型,它不能有效地替代T extends Parent<T> - shmosel
@SotiriosDelimanolis,您链接的问题没有解决如何创建Pet实例(如果它不是抽象的),这是OP在这里提出的问题。 - shmosel
显示剩余6条评论
1个回答

9

extends 的意思是“是或者扩展”。你的示例无法编译的原因是内部的Parent是原始类型,而不是T extends Parent<T>的有效替代品。"正确"的类型应该像这样:Parent<Parent<Parent<...>>>无限循环下去。显然这样的类型是不可能声明的。

一个解决方案是像这样进行实例化:

Parent<?> parent = new Parent<>();
Parent<?> derived = parent.function();

这可以行得通是因为编译器已经知道 TParent<?> 的某个子类。这种技巧的一个缺点是,如果类型无法推断,例如使用匿名类时它将无法正常工作。
另一个可能的方法,取决于父/子关系的性质,是创建一个额外的类来扩展基类,仅用于其类型解析:
// Parent functionality in here
public static abstract class Base<T extends Base<T>> {}

// This can be empty, or have just constructors if necessary
public static class Simple extends Base<Parent> {}

// Child functionality in here
public static class Extended extends Base<Extended> {}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接