Java泛型类型,可以扩展,也可以是父类 [英] Java generic type that either extends or is a parent class

查看:318
本文介绍了Java泛型类型,可以扩展,也可以是父类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一些如下所示的代码:

I am looking for some code that would look like below:

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的实例而不用函数()向下转换返回对象)

This is so any child classes will have access to the other parent functions, yet will remain independent classes (without upcasting the return value of function() to an instance of Parent). And the programmer can also use the Parent class independently as well (so an instance of Parent can be created without function() downcasting the return object)

实现:

public class Child extends Parent<Child> {}

用法:

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

为了概述差异,这不是方法链的问题。相反,当父类接受子类的泛型时,它不能再单独用作类(使用上面的代码),因为 new Parent< Parent>()将无法编译(将 is_or_extends 替换为 extends

Just to outline a difference, this is not an issue with method chaining. Rather when the parent class takes in a generic of a child class, it can no longer be used as a class in its own right (using the code above), because new Parent<Parent>() will not compile (when replacing "is_or_extends" with "extends")

我的目标:

我想要实现的是父类,当扩展时,函数( )将返回子类的对象而不是父类。

What I am aiming to achieve is a parent class that when extended, function() will return an object of the child class rather than the parent class.

我会使用泛型类型来告诉父类哪个子类class调用了函数,但是我不能再使用父类的对象而不会遇到异常。下面是一个例子:

I would use a generic type to tell the parent class which child class called the function, but I can no longer use an object of the parent class itself without experiencing exceptions. An example is below:

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();
}

提前致谢。

推荐答案

extends 表示是或扩展。您的示例无法编译的原因是因为内部 Parent 是原始类型,它不是的有效替代.T extends Parent< T> 。 正确类型如下所示: Parent< Parent< Parent< ...>>> ad infinitum。显然这种类型是不可能声明的。

extends does mean "is or extends". The reason your example doesn't compile is because the inner Parent is a raw type, which is not a valid substitute for T extends Parent<T>. The "correct" type would look like this: Parent<Parent<Parent<...>>> ad infinitum. Obviously such a type is impossible to declare.

一种解决方案就是像这样实例化它:

One solution is to instantiate it like this:

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

这很有效,因为编译器已经知道 T Parent<?> 的某些子类。这个技巧的一个缺点是,如果无法推断类型,它将无法工作,例如使用匿名类时。

This works because the compiler already knows that T is some subclass of Parent<?>. One disadvantage of this trick is that it won't work if the type can't be inferred, for example when using anonymous classes.

另一种可能的方法 - 取决于父/子关系的本质 - 是创建一个额外的类来扩展基础,只是为了它的类型解析:

Another possible approach - dependent on the nature of parent/child relationship - is to create an additional class to extend the base, just for its type resolution:

// 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> {}

这篇关于Java泛型类型,可以扩展,也可以是父类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆