涉及inheritance和此的Javagenerics

我有一个(对我来说)复杂的Javagenerics问题。 我阅读了一些文档,并了解了一些,但肯定不是我应该做的全部。 基本上,对我来说,试图解决它会导致尝试和错误。

在下文中,我给出了一个我的代码的简要示例,一次没有任何generics(因此可以希望了解我想要实现的内容),另一个附加一些更接近解决方案的附加内容。 请更正我的第二个版本和/或指向我的具体文档。 (我有Javagenerics的一般文档。但我的代码似乎有几个干扰的挑战,很难找到正确的解决方案)

关于我的例子:有一个抽象基类型和几个实现变量(只给出一个)。 方法combine()调用getOp1() ,它决定(取决于 )它是应该在自己的实例上运行还是在新实例上运行。 计算完成后,返回目标实例。

 abstract class Base { protected final Base getOp1() { if(Util.isConditionMet()) { return getNewInstance(); } else { return this; } } protected abstract Base getNewInstance(); // returns a new instance of an implementing class public abstract Base combine(Base other); } class Variant extends Base { public Variant getNewInstance() { return new Variant(); } public combine(Variant op2) { Variant op1 = getOp1(); op1.calculate(op2); return op1; } private void calculate(Variant other) { /* some code */ } } 

添加了一些generics的版本。 此版本有问题,无法编译。

 abstract class Base<T extends Base> { protected final T getOp1() { if(Util.isConditionMet()) { return getNewInstance(); } else { return this; } } protected abstract T getNewInstance(); // returns a new instance of an implementing class public abstract T combine(T other); } class Variant<T extends Variant> extends Base { protected T getNewInstance() { return new Variant(); } public T combine(T op2) { T op1 = getOp1(); op1.calculate(op2); return op1; } private void calculate(T other) { /* some code */ } } 

要使此代码有效,您需要解决不兼容性类型问题:用Base替换T返回类型,并将Variant#getOp1()结果Variant#getOp1()Variant以允许对其调用calculate() (这在这里是安全的)因为Variant#getOp1()总是返回Variant

 abstract class Base> { protected final Base getOp1() { return condition() ? getNewInstance() : this; } protected abstract Base getNewInstance(); public abstract Base combine(T other); } class Variant> extends Base { protected Base getNewInstance() { return new Variant(); } public Base combine(T op2) { Variant op1 = (Variant) getOp1(); // <- explicit cast op1.calculate(op2); return op1; } private void calculate(Base other) { // ... } } 

顺便说一句,我仍然没有看到这种复杂类型结构的原因。

我见过几个这样的组合操作课程,但从未过于复杂。 也许inheritance不是正确的工具。

最好使用查找机制来实现function。

 class Base { // Untyped private Map, Object> capabilities = new HashMap<>(); protected  void register(Class intf, I obj) { capabilities.put(intf, obj); } public  Optional lookup(Class intf) { Object obj = capabilities.get(intf); return obj == null ? Optional.emtpy() : Optional.of(intf.cast(obj)); } } interface Flying { void fly(double altitude); } Base pelican = new Pelican(); Flying flying = pelical.lookup(Flying.class).orElse(null); flying.fly(0.5); 

这也允许动态变化,并结合两个方面的事物。