繁体   English   中英

有什么方法可以在超类中定义泛型方法以引用继承类的类型?

[英]Is there any way to define a generic method in a super class to reference the inheriting class's type?

当定义类似此方法的内容时:

class State {
   public void addOperator(Operator<? extends State> op) {
   }
}

有什么办法可以这样定义它:

class State {
  public void addOperator(Operator<? extends this.getClass()> op) {
  }
}

这样,从国家继承的任何阶级都会迫使所有传递的价值都符合其阶级类型。

我知道上面的方法行不通,但是是否有办法强制通用通配符至少与当前的类类型匹配?

您已经接受了一个声称无法用Java表示所需约束的答案。 如果我正确理解要求,那么以下解决方案将告一段落。

// You didn't flesh out what an operator does or provides,
// so I'll just make something up.
interface Operator<T> {
  void apply(T arg);
}

// Request that a derived type provide its own type as a type
// parameter, per the Curiously Recurring Template Pattern (CRTP).
abstract class State<T extends State> {
  public void addOperator(Operator<? extends T> op) {
    final PrintStream s = System.out;
    s.print("Received an operator of concrete type ");
    s.print(op.getClass().getName());
    s.println('.');
  }
}

final class DerivedState extends State<DerivedState> {
}

public class Driver {
  public static void main(String[] args) {
    DerivedState ds = new DerivedState();
    ds.addOperator(new Operator<DerivedState>() {
      // ...
    });

    // And the following will not compile:
    ds.addOperator(new Operator<Integer>() { /* ... */ });
  }
}

注意, DerivedTypeapply()方法将只接受类型参数为DerivedType或从DerivedType派生的某种类型的Operator参数,但由于DerivedType是最终类型,因此不存在其他此类类型。

我们无法做的(可能是Chris所暗示的)是强制提供给State的类型参数实际上是派生类型本身。 我们不能阻止以下定义,其中一个类提供另一个作为State的类型参数:

final class AnotherDerivedState extends State<DerivedState> {
}

在这里,可以使用Operator<DerivedState>调用AnotherDerivedState#addOperator() ,该Operator<DerivedState>显然不是 Operator<AnotherDerivedState>类型。

您不能阻止某人“不正确地”导出State ,但是如果您假设人们会遵循预期的派生模式,则可以帮助他们安全地使用图书馆的其余部分。

由于包含多态性,可以随时使用子类代替超类。

尝试写作

State.class

获取状态的Class对象。

class State {
  public void addOperator(Operator<? extends State.class> op) {
  }
}

尽管我不确定Class对象是否在它们之间继承,但是它们使用泛型Class<T>

假设我们有class Base class Derived extends Base Class<Derived>可能会扩展Class<Base>

相反,这种情况看起来更有希望

class State {
  public void addOperator(Operator<Class<? extends State>> op) {
  }
}

暂无
暂无

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

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