简体   繁体   English

扩展或为父类的Java泛型类型

[英]Java generic type that either extends or is a parent class

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

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). 这样,任何子类都可以访问其他父函数,但仍将保持独立类(无需将function()的返回值上载到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) 而且程序员也可以独立使用Parent类(因此,可以在不使用function()下投返回对象的情况下创建Parent的实例)

Implementation: 实现方式:

public class Child extends Parent<Child> {}

Usage: 用法:

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

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 ") 而是当父类采用子类的泛型时,就不能再单独使用它作为类(使用上面的代码),因为new Parent<Parent>()不会编译(替换“ is_or_extendsis_or_extends “与“ extends ”)

My Goal: 我的目标:

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. 我的目标是实现一个父类,当扩展该类时, function()将返回子类的对象,而不是父类。

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

Thanks in advance. 提前致谢。

extends does mean "is or extends". 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> . 您的示例未编译的原因是因为内部的Parent是原始类型,它不是T extends Parent<T>的有效替代。 The "correct" type would look like this: Parent<Parent<Parent<...>>> ad infinitum. “正确”类型如下所示: 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();

This works because the compiler already knows that T is some subclass of Parent<?> . 之所以可行,是因为编译器已经知道TParent<?>某个子类。 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> {}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM