Java泛型涉及继承和这个 [英] Java generics involving inheritance and this

查看:160
本文介绍了Java泛型涉及继承和这个的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



在下面,我给出了一个我的代码的简明例子,一次没有任何泛型(所以人们可以理解我想实现的目标),另一个有一些增加这更接近解决方案。请更正我的第二个版本和/或指向我的具体文档。 (我有Java泛型的一般文档,但我的代码似乎有几个干扰性的挑战,很难找到正确的解决方案)。关于我的例子:有一个摘要基本类型和几个实现变体(只给出一个)。方法 combine()调用 getOp1(),它决定(取决于<某些条件> ; )如果它应该在自己的实例上或者在新的实例上运行。计算完成后,它返回目标实例。

 抽象类Base {
protected Base getOp1(){
if(Util.isConditionMet() ){return getNewInstance(); }
else {return this; }
}
protected get BaseNewInstance(); //返回一个实现类的新实例
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);
返回op1;

private void calculate(Variant other){/ *一些代码* /}
}

添加了一些泛型的版本。

 抽象类Base< T extends Base< T>> {
protected final T getOp1(){
if(Util.isConditionMet()){return getNewInstance(); }
else {return this; }
}
protected abstract T getNewInstance(); //返回一个实现类的新实例
public abstract T combine(T other);
}

class Variant< T extends Variant< T>>延伸Base< T> {
protected T getNewInstance(){return new Variant(); }
public T combine(T op2){
T op1 = getOp1();
op1.calculate(op2);
返回op1;

private void calculate(T other){/ * some code * /}
}

$ b $为了使这段代码正常工作,你需要解决不兼容类型的问题:把 T 返回类型替换为 Base< T> 并将 Variant#getOp1()转换为变体< T> 允许调用 calculate()就可以了(因为 Variant#getOp1()总是返回变体

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



class Variant< T extends Variant< T> >扩展Base< T> {
受保护的Base< T> getNewInstance(){
返回新的Variant();
}

public Base< T>结合(T op2){
Variant< T> op1 =(Variant< T>)getOp1(); //< - 显式转换
op1.calculate(op2);
返回op1;
}

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



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


I have a (for me) complex Java generics problem. I read through some documentation and understand some but certainly not all of what I should. Basically, for me, trying to solve it would result in try and error.

In the following, I give a condensed example of my code, once without any generics (so one can hopefully understand what I want to achieve) and the other with some additions that come closer to the solution. Please correct my second version and/or point me to specific documentation. (I have general documentation of Java generics. But my code seems to have several interfering challenges and it is hard to a correct solution)

About my example: There is an abstract base type and several implementing variants (only one is given). Method combine() calls getOp1(), which decides (depending on <some condition>) if it should operate on its own instance or on a new one. After the calculation, it returns the target instance.

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

The version with some generics added. This version is faulty and does not compile.

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

解决方案

To make this code working, you need to resolve incompatibility type issues: replace T returning types by Base<T> and cast result of Variant#getOp1() to Variant<T> to allow invoke calculate() on it (this is safe here because Variant#getOp1() always returns 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) { 
        // ...
    }
}

Btw, I still see no reason of such complicated type structure.

这篇关于Java泛型涉及继承和这个的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆