有没有办法在超类中定义泛型方法来引用继承类的类型?

时间:2015-05-24 15:11:48

标签: java generics

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

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

有没有办法以这种方式定义它:

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

因此,任何从 State 中继承的类强制所有传入的值都符合其类类型。

我知道上面的内容不会起作用,但无论如何都要强制使用通用外卡来至少匹配当前的类类型?

3 个答案:

答案 0 :(得分:2)

您已经接受了一个答案,声称您所希望的约束不能用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>() { /* ... */ });
  }
}

请注意,DerivedType的{​​{1}}方法只接受类型参数为apply()的{​​{1}}参数 - 或者从{{1}派生的某种类型},但由于Operator是最终的,因此不存在其他类型。

我们可以做什么 - 这可能是Chris所暗示的 - 要求提供给DerivedType的类型参数实际上是派生类型本身。我们无法阻止以下定义,其中一个类提供另一个类作为DerivedType的类型参数:

DerivedType

在这里,可以使用State来呼叫Statefinal class AnotherDerivedState extends State<DerivedState> { } 显然

您无法阻止某人来自AnotherDerivedState#addOperator()&#34;错误地&#34;,但如果您认为人们会遵循预期的推导模式,您可以帮助他们使用其他人图书馆安全。

答案 1 :(得分:-1)

由于包含多态性,可以随时使用子类而不是超类。

答案 2 :(得分:-2)

尝试写作

State.class

获取State的Class对象。

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

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

所以我们假设我们有class Baseclass Derived extends BaseClass<Derived>可能确实扩展了Class<Base>

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

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