我经常发现自己想要写的形式避免泛型类型形式的Foo <ActualType延伸富<ActualType>>
public class Foo<ActualType extends Foo<ActualType>>
例如在这样的设置的通用类定义:
public interface ChangeHandler<SourceType> {
public void onChange(SourceType source);
}
public class Foo<ActualType extends Foo<ActualType>> {
private final List<ChangeHandler<ActualType>> handlers = new ArrayList<>();
public void addChangeHandler(ChangeHandler<ActualType> handler) {
handlers.add(handler);
}
@SuppressWarnings("unchecked")
protected void reportChange() {
for (ChangeHandler<ActualType> handler: handlers)
handler.onChange((ActualType) this);
}
}
public class Bar extends Foo<Bar> {
// things happen in here that call super.reportChange();
}
public static void main(String[] args) throws IOException {
Bar bar = new Bar();
bar.addChangeHandler(new ChangeHandler<Bar>() {
@Override
public void onChange(Bar source) {
// Do something with the changed object
}
});
}
这里的变化事件只是一个例子。当我想让超类为每个特定的子类提供“个性化”的功能时(不确定如何更好地描述这个更好......),这更多的是我遇到的一个普遍问题在“个性化”之上的事实是ChangeHandler
被称为具有实际子类型的对象(Bar
)而不是调用处理程序的超类的类型(Foo
)。
不知何故这种方法对我来说似乎有点混乱。它实际上允许潜在的问题,因为没有什么能阻止我从那时候定义:
public class Baz extends Foo<Bar> { /* ... */ }
是否有一个更清洁的替代?
的圣杯将是始终定义包含当前类的一些类型的参数,像this.getClass()
静态版本,让我写这样的事情,而不是:
public class Foo {
private final List<ChangeHandler<this.Class>> handlers = new ArrayList<>();
public void addChangeHandler(ChangeHandler<this.Class> handler) {
handlers.add(handler);
}
protected void reportChange() {
for (ChangeHandler<this.Class> handler: handlers)
handler.onChange(this);
}
}
凡this.Class
会等于Bar
,类型为Bar
。
看不出这是Java的版本[CRTP]的(https://stackoverflow.com/questions/4173254/what-is-the-curiously-recurring-template-pattern-crtp)。这很典型。 – dhke
圣杯会很好,但它不存在(还)。由于继承,静态检查似乎很困难。 – Radiodef
难道你不能'Foo>',用'T'替换'ActualType'的所有出现?不需要'ActualType'。不知道这是什么意思的“更清洁” –