8

我不断回到这个问题的变体:它可能有一个非常简单的解决方案,但我似乎无法弄清楚......

我有一堆 xQuantity 形式的类,例如 DistanceQuantity、AreaQuantity 等,它们扩展了一个类 DimensionQuantity。现在您可以添加或减去DistanceQuantity或AreaQuantity等,但不能混合它们,所以我认为我需要在子类中有(短)add,subtract等方法,但我想减少任何逻辑重复到最低限度。但是,我需要返回子类的一个对象,这似乎很难从超类方法中做到。我相信这可以使用反射来完成,但是AFAIK您仍然需要在子类方法的最后进行强制转换,并且我被告知反射可能很昂贵......到目前为止我想出的最好的是:

在 DistanceQuantity (和其他类似的)中:

public DistanceQuantity() {     
}

public DistanceQuantity add(DistanceQuantity d1) {
    DistanceQuantity dn = new DistanceQuantity(); 
    Object o = super.add(dn, this, d1, DistanceUnit.REF_UNIT);
    return (DistanceQuantity) o;
}

在 DimensionQuantity 中(减去一些不太相关的语句):

public Object add(DimensionQuantity dn, DimensionQuantity d1, DimensionQuantity d2, 
  AbstractUnit au) {
    dn.unit = au;
    dn.scalar = d1.scalar + d2.scalar;
    dn.units = dn.scalar;    
    return dn;   
}

任何人都可以提出更精简的代码 - 仍然是类型安全的吗?TIA

4

3 回答 3

11

您可以像这样使用泛型:

public abstract class DimensionQuantity<T extends DimensionQuantity>{
    public abstract T add(T parameter);
}

你像这样扩展它:

public class DistanceQuantity extends DimensionQuantity<DistanceQuantity>{
    public DistanceQuantity add(DistanceQuantity parameter){
        //Whatever
        return null;
    }
}

对于最初的问题,拥有一个使用其子类之一的超类是一个非常糟糕的主意(也是一种糟糕的做法)。


资源 :

在同一主题上:

于 2010-08-30T19:18:08.283 回答
0

为维度创建一个枚举:

公共枚举维度{区域,距离,...}

扔掉你的子类。而是只创建 DimensionQuantity 对象,并强制每个对象都有一个(不可变的)Dimension,在创建时设置。

在DimensionQuantity中实现加法,首先检查被加的两个量的Dimensions是否相同。

瞧!更少的类,类型安全,没有重复的代码。

于 2010-08-30T20:41:02.307 回答
0

在 Java 6 中,您可以尝试类似的方法。但是使用泛型也是一个好主意:

public abstract class DimensionQuantity {

    protected int quantity;

    public DimensionQuantity (int quantity) {
        this.quantity = quantity;
    }

    public abstract DimensionQuantity add(DimensionQuantity dq);
}

public class DistanceQuantity extends DimensionQuantity {

    public DistanceQuantity(Quantity quantity) {
        super(quantity);
    }

    /* 
     * A sub-class as return type is authorized.
     * If dq is not a DistanceQuantity, a ClassCastException is thrown, but you can change this.
     */
    @Override 
    public DistanceQuantity add(DimensionQuantity dq) throws ClassCastException {
        return new DistanceQuantity(this.quantity + (DistanceQuantity) dq.quantity);
    }
}
于 2010-08-30T19:23:45.150 回答