繁体   English   中英

涉及继承的Java泛型

[英]Java generics involving inheritance and this

我有一个(对我而言)复杂的Java泛型问题。 我通读了一些文档,并了解了我应该了解的一些但不是全部。 基本上,对我来说,尝试解决它会导致尝试和错误。

在下面的内容中,我给出了代码的精简示例,一次没有任何泛型(这样就可以希望理解我想要实现的目标),而另一个则有一些更接近解决方案的附加内容。 请更正我的第二个版本和/或指向特定的文档。 (我有Java泛型的常规文档。但是我的代码似乎遇到了一些干扰性的挑战,因此很难找到正确的解决方案)

关于我的示例:有一个抽象的基本类型和几个实现的变体(仅给出一个)。 方法getOp1() combine()调用getOp1() ,该方法确定(取决于<some condition> )应在自己的实例上还是在新实例上进行操作。 计算后,它将返回目标实例。

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 */ }
} 

添加了一些泛型的版本。 该版本有故障,无法编译。

abstract class Base<T extends Base<T>> {
    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<T>> extends Base<T> {
    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 */ }
}

我从没有见过这么复杂的例子,但我见过几个这样的组合的,可操作的类。 也许继承不是正确的工具。

最好对功能,特征使用查找机制。

class Base {

    // Untyped
    private Map<Class<?>, Object> capabilities = new HashMap<>();

    protected <I> void register(Class<I> intf, I obj) {
        capabilities.put(intf, obj);
    }

    public <T> Optional<T> lookup(Class<T> 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);

这还允许动态更改,并在两个方面进行组合。

为了使此代码正常工作,您需要解决不兼容类型的问题:用Base<T>替换T返回类型,并将Variant#getOp1()结果Variant#getOp1()Variant<T>以允许在其上调用calculate() (这是安全的)因为Variant#getOp1()始终返回Variant

abstract class Base<T extends Base<T>> {
    protected final Base<T> getOp1() {
         return condition() ? getNewInstance() : this;
    }
    protected abstract Base<T> getNewInstance(); 
    public abstract Base<T> combine(T other);
}



class Variant<T extends Variant<T>> extends Base<T> {
    protected Base<T> getNewInstance() { 
        return new Variant(); 
    }

    public Base<T> combine(T op2) {
        Variant<T> op1 = (Variant<T>) getOp1();   // <- explicit cast
        op1.calculate(op2);
        return op1;
    }

    private void calculate(Base<T> other) { 
        // ...
    }
}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM