简体   繁体   English

从超类方法返回子类对象

[英]Returning subclass object from superclass method

I keep coming back to variants of this problem: it probably has a very simple solution, but I can't seem to figure it out... 我一直回到这个问题的变种:它可能有一个非常简单的解决方案,但我似乎无法弄清楚...

I have a bunch of classes of the form xQuantity, eg DistanceQuantity, AreaQuantity, etc., which extend a class DimensionQuantity. 我有一堆xQuantity形式的类,例如DistanceQuantity,AreaQuantity等,它们扩展了一个DimensionQuantity类。 Now you can add or subtract DistanceQuantity's or AreaQuantity's, etc., but you can't mix them, so I think I need to have (short) add, subtract, etc., methods in the subclasses, but I want to reduce any logic duplication to a minimum. 现在你可以添加或减去DistanceQuantity或AreaQuantity等,但你不能混合它们,所以我认为我需要在子类中有(短)加,减等方法,但我想减少任何逻辑重复到最低限度。 However, I need to return an object of the subclass, and this seems difficult to do from the superclass method. 但是,我需要返回子类的对象,这似乎很难从超类方法中做到。 I believe this can be done using reflection, but AFAIK you still need to do a cast at the end in the subclass method, and I am told that reflection can be expensive... The best I have come up with so far is: 我相信这可以使用反射来完成,但AFAIK你仍然需要在子类方法的最后做一个演员,而且我被告知反射可能很昂贵......到目前为止我想出的最好的是:

In DistanceQuantity (and the other similar ones): 在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;
}

In DimensionQuantity (minus some less relevant statements): 在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;   
}

Can anyone come up with leaner code - that is still type-safe? 任何人都可以提出更精简的代码 - 这仍然是类型安全的吗? TIA TIA

You can use Generics like this : 你可以像这样使用泛型:

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

and you extends it like this : 你像这样扩展它:

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

And for the initial question, it's a really bad idea (and a bad practice) to have a superclass which uses one of its sub-classes. 对于最初的问题,拥有一个使用其子类之一的超类是一个非常糟糕的想法(也是一个不好的做法)。


Resources : 资源:

On the same topic : 在同一主题上:

In Java 6, you can try something like that. 在Java 6中,您可以尝试类似的东西。 But using generics is also a good idea : 但使用泛型也是一个好主意:

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);
    }
}

Create an enum for the Dimensions: 为Dimensions创建枚举:

public enum Dimension { AREA, DISTANCE,...} public enum Dimension {AREA,DISTANCE,...}

Throw away your subclasses. 扔掉你的子类。 Instead create only DimensionQuantity objects, and force each to have an (immutable) Dimension, set at create time. 而是仅创建DimensionQuantity对象,并强制每个对象具有在创建时设置的(不可变)维度。

Implement addition in DimensionQuantity, first checking that the Dimensions of the two quantities being added are the same. 在DimensionQuantity中实现添加,首先检查要添加的两个量的维度是否相同。

Voila! 瞧! Fewer classes, type safety, no duplicate code. 类更少,类型安全,没有重复的代码。

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

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