2015-11-30 3 views
0

фон:Полиморфизма дизайн вино

У меня 4 классов, которые представляют собой единицу измерения: мм, дюйм, пиксель, FootAndInch.

Каждый класс является классом-оболочкой для BigDecimal, каждый из них имеет такое же подмножество методов:

... 
add(BigDecimal value) 
divide(BigDecimal value) 
multiple(BigDecimal value) 
subtract(BigDecimal value) 
... 

Это казалось утомительным повторять одни и те же методы в каждом отдельном классе. Так что я создал абстрактный класс (так называемый «Unit»), надеясь, я бы только писать каждый метод один раз и использовать полиморфизм:

public abstract class Unit { 

BigDecimal value; 

public Unit(BigDecimal value) { 
    this.value = value; 
} 
public Unit(int value) { 
    this.value = new BigDecimal(value); 
} 
public Unit(String value) { 
    this.value = new BigDecimal(value); 
} 
public Unit(Unit unit) { 
    this.value = unit.bigDecimal(); 
} 

public abstract Unit add(int value); 
public abstract Unit add(int value, MathContext mathContext); 
public abstract Unit add(Unit value); 
public abstract Unit add(Unit value, MathContext mathContext); 
public abstract Unit add(BigDecimal value); 
public abstract Unit add(BigDecimal value, MathContext mathContext); 

public abstract Unit divide(Unit value, MathContext mathContext); 
public abstract Unit divide(int value, MathContext mathContext); 
public abstract Unit divide(BigDecimal value, MathContext mathContext); 

public abstract Unit[] divideAndRemainder(Unit value, MathContext mathContext); 

public abstract Unit multiply(BigDecimal value); 
public abstract Unit multiply(BigDecimal value, MathContext mathContext); 
public abstract Unit multiply(int value); 
public abstract Unit multiply(int value, MathContext mathContext); 
public abstract Unit multiply(Unit value); 
public abstract Unit multiply(Unit value, MathContext mathContext);  

public abstract Unit negate(); 
public abstract Unit plus(); 
public abstract Unit remainder(Unit value, MathContext mathContext); 

public abstract Unit subtract(int value); 
public abstract Unit subtract(int value, MathContext mathContext); 
public abstract Unit subtract(Unit value); 
public abstract Unit subtract(Unit value, MathContext mathContext); 
public abstract Unit subtract(BigDecimal value); 
public abstract Unit subtract(BigDecimal value, MathContext mathContext); 

public double doubleValue() { 
    return value.doubleValue(); 
}  
public float floatValue() { 
    return value.floatValue(); 
}  
public int intValue() { 
    return value.intValue(); 
} 
public BigDecimal bigDecimal() { 
    return value; 
} 

@Override public abstract String toString();  
} 

А теперь Мм, дюймы, Pixel, FootAndInch каждый простираться блок

Проблема: следующий оператор поднимает ошибку:

Mm value1 = new Mm(1000); 
Mm result = value1.divide(new Mm(10), new MathContext(10, RoundingMode.CEILING)); 

«несовместимые типы: Устройство не может быть преобразован в Мт».

Я понимаю ошибку, но я не знаю, как изменить порядок кода, чтобы только писать методы. Любой совет?

Редактировать: Чтобы уточнить, методы класса Unit реализованы в классе Unit. Я не включил их, чтобы попытаться укоротить вопрос.

+0

Вы считали параметризацию своих классов? –

+0

Является ли это таким же, как Generics? – cworner1

+0

Да, по-видимому, я забыл правильный термин –

ответ

0

Я вижу 2 варианта: либо сделать только 1 класс, который сохраняет int и перечисление для типа измерения (не требуется никакого полиморфизма). Или превратите Единицу в универсальный блок суперкласса и сделайте все свои абстрактные функции возвратом типа T. Затем определите Mm как класс Mm extends Unit.

+0

Каждый подкласс имеет способ преобразования его значения в другой, например, например: Класс Mm имеет методы toInch(), toPixel(), toFootAndInch(). Это выходит за пределы перечисления, правильно? Я рассмотрю Generics, спасибо. – cworner1

+0

Посмотрите, как работает сравнение . Это хорошая рекомендация. – Shloim

+0

Также смотрите, как работает TimeUnit, это хороший пример для первого варианта. – Shloim