仅接受实现类类型的抽象方法的定义

时间:2018-01-05 09:05:00

标签: java generics

目标:定义一个抽象方法,该方法接受实现类的类型(或子类型)的引用。

我想出的是:

public abstract class Parent<T extends Parent> {
    public abstract void foo(T t);
}

实施可能是:

public class Child extends Parent<Child> {
    public void foo(Child child) { /* ... */ }
}

乍一看,这看起来是一个令人满意的解决方案,但它也允许以下实施:

public class Child1 extends Parent<Child> {
    public void foo (Child child) { /* ... */ }
}

有没有办法定义抽象方法来阻止第二次实现?

1 个答案:

答案 0 :(得分:1)

在编译时强制这种约束是不完全可能的。但是你可以使违反这种约束更加麻烦:

abstract class Parent<T extends Parent> {

   protected Parent(Class<T> clazz) {
      if (!this.getClass().equals(clazz))  {
         throw new IllegalArgumentException("you must pass this; invalid attempt to extend Parent where subclass does not assign T to itself.
      }
   }
   // ...
}  

class GoodChild extends Parent<GoodChild> {
   public GoodChild() { super(GoodChild.class) };
}

class BadChild extends Parent<GoodChild> {
   public BadChild() { super(BadChild.class) }; // cannot compile.
}

class WorstChild extends Parent<GoodChild> {
   public WorstChild() { super(GoodChild.class); } // compiles but will fail in run-time.
}

class CircularChild extends Parent<Parent> {
   public CircularChild() { super(Parent.class); } // compiles but will fail
}

诀窍是父构造函数代码在运行时绑定this的类与T相同的类是你想要的。