Возвращение объекта подкласса из метода суперкласса

Я продолжаю возвращаться к вариантам этой проблемы: она, вероятно, имеет очень простое решение, но я не могу понять это ...

У меня есть куча классов в форме xQuantity, например DistanceQuantity, AreaQuantity и т. д., которые расширяют класс DimensionQuantity. Теперь вы можете добавлять или вычитать DistanceQuantity или AreaQuantity и т. Д., Но вы не можете смешивать их, поэтому я думаю, что мне нужно иметь (короткие) методы сложения, вычитания и т. Д. В подклассах, но я хочу уменьшить любую логику дублирование до минимума. Однако мне нужно вернуть объект подкласса, а это кажется трудным сделать с помощью метода суперкласса. Я считаю, что это можно сделать с помощью рефлексии, но 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

8
задан tangens 30 August 2010 в 19:14
поделиться

3 ответа

В 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);
    }
}
0
ответ дан 5 December 2019 в 18:55
поделиться

Вы можете использовать Generics следующим образом:

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

И для первоначального вопроса, это действительно плохая идея (и плохая практика) иметь суперкласс, который использует один из своих подклассов.


Ресурсы:

На ту же тему:

9
ответ дан 5 December 2019 в 18:55
поделиться

Создайте перечисление для измерений:

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

Выбросьте свои подклассы. Вместо этого создавайте только объекты DimensionQuantity и заставляйте каждый из них иметь (неизменяемое) измерение, установленное во время создания.

Реализуйте добавление в DimensionQuantity, предварительно проверив, что размеры двух добавляемых величин совпадают.

Вуаля! Меньше классов, безопасность типов, отсутствие повторяющегося кода.

0
ответ дан 5 December 2019 в 18:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: