目标:定义一个抽象方法,该方法接受实现类的类型(或子类型)的引用。
我想出的是:
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) { /* ... */ }
}
有没有办法定义抽象方法来阻止第二次实现?
答案 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
相同的类是你想要的。