2012-10-01 22 views
4

我有不同類表示不同的單位(體積,重量,距離),枚舉的值用於將轉換值存儲爲基本類型。不同類型的單元的抽象類

問題是,有很多代碼重複和 我相信有一種優雅的方式來編寫一個抽象類,可以避免它。 我不知道我應該如何申報這個課程。 下面是音量類:

import java.math.BigDecimal; 

import lombok.Data; 

@Data 
public class Volume { 

public enum Unit 
{ 
    CUBIC_METER(new BigDecimal("1")), // CUBIC_METER 
    // 1 m3 = 61023.7 inch3 
    CUBIC_INCH(new BigDecimal("61023.7")); 
    private Unit(BigDecimal m3Value) 
    { 
     this.m3Value = m3Value; 
    } 

    public final BigDecimal m3Value; 
} 
// internally, we store the volume in m3 
private final BigDecimal volumeInM3; 

public Volume() 
{ 
    volumeInM3 = BigDecimal.ZERO; 
} 

public Volume(final String volumeValue, final Unit volumeUnit) 
{ 
    this(new BigDecimal(volumeValue), volumeUnit); 
} 

public Volume(final BigDecimal volumeValue, final Unit volumeUnit) 
{ 
    if (volumeValue.signum() == 0) 
    { 
     volumeInM3 = BigDecimal.ZERO; 
    } 
    else 
    { 
     volumeInM3 = volumeValue.divide(volumeUnit.m3Value, NumberUtil.MC); 
    } 
} 

/** 
* Return the volume in the unit given in param 
* @param volumeUnit 
* @return 
*/ 
public BigDecimal getAs(final Unit volumeUnit) 
{ 
    return volumeInM3.multiply(volumeUnit.m3Value, NumberUtil.MC); 
} 

public Volume add(final Volume volumeToAdd) 
{ 
    BigDecimal newVolumeValue = volumeToAdd.volumeInM3.add(volumeInM3, NumberUtil.MC); 
    return new Volume(newVolumeValue, Volume.Unit.CUBIC_METER); 
} 

public Volume divide(final Volume divisor) 
{ 
    BigDecimal newVolumeValue = volumeInM3.divide(divisor.volumeInM3, NumberUtil.MC); 
    return new Volume(newVolumeValue, Volume.Unit.CUBIC_METER); 
} 

public boolean isZero() 
{ 
    if (volumeInM3.signum() == 0) 
     return true; 
    return false; 
} 

public boolean isEqual(final Volume another) 
{ 
    if (volumeInM3.compareTo(another.volumeInM3) == 0) 
     return true; 
    return false; 
} 
} 

這裏是頗爲相似的重量級別:

import java.math.BigDecimal; 

import lombok.Data; 

@Data 
public class Weight { 

// the value stored with enum is the value used to convert the unit to kilogramm, 
// wich is the reference unit 
public enum Unit 
{ 
    KILOGRAM(new BigDecimal("1")), 
    // 1 kg = 1000 g 
    GRAM(new BigDecimal("1000")), 
    // 1 kg = 2.20462 pounds 
    POUND(new BigDecimal("2.20462")); 

    private Unit(BigDecimal kgValue) 
    { 
     this.kgValue = kgValue; 
    } 

    private final BigDecimal kgValue; 
} 

// internally, we store the weight inKg 
private final BigDecimal weightInKg; 

public Weight() 
{ 
    weightInKg = BigDecimal.ZERO; 
} 

public Weight(final String weightValue, final Unit weightUnit) 
{ 
    this(new BigDecimal(weightValue), weightUnit); 
} 

public Weight(final BigDecimal weightValue, final Unit weightUnit) 
{ 
    if (weightValue.signum() == 0) 
    { 
     weightInKg = BigDecimal.ZERO; 
    } 
    else 
    { 
     weightInKg = weightValue.divide(weightUnit.kgValue, NumberUtil.MC); 
    } 
} 

/** 
* Return the weight in the unit given in param 
* @param weightUnit 
* @return 
*/ 
public BigDecimal getAs(final Unit weightUnit) 
{ 
    return weightInKg.multiply(weightUnit.kgValue, NumberUtil.MC); 
} 

public Weight add(final Weight weightToAdd) 
{ 
    BigDecimal newWeightValue = weightToAdd.weightInKg.add(weightInKg, NumberUtil.MC); 
    return new Weight(newWeightValue, Weight.Unit.KILOGRAM); 
} 

public Weight divide(final Weight divisor) 
{ 
    BigDecimal newWeightValue = weightInKg.divide(divisor.weightInKg, NumberUtil.MC); 
    return new Weight(newWeightValue, Weight.Unit.KILOGRAM); 
} 
public boolean isZero() 
{ 
    if (weightInKg.signum() == 0) 
     return true; 
    return false; 
} 

public boolean isEqual(final Weight another) 
{ 
    if (weightInKg.compareTo(another.weightInKg) == 0) 
     return true; 
    return false; 
} 
} 

當instanciating音量,用戶被迫明確地提供單位。

Volume myCubicMeter, myCubicInch; 
myCubicMeter = new Volume("1", Volume.Unit.CUBIC_METER); 
myCubicInch = new Volume("1", Volume.Unit.CUBIC_INCH); 

我想要實現的是一個抽象類,它將實現所有的方法並強制子類實現枚舉值。 什麼是正確的方法來做到這一點?

+0

你可能想看看jscience HTTP://www.unitsofmeasurement .org /看看他們做了什麼 –

回答

1

在Java中,枚舉類是所提供的Enum類的子類。

你不能給它們一個共同的抽象祖先,你也不能將它們繼承。如果你真的想用一組枚舉來保留指向你的單元的商品的編譯時間常量,那麼你就不能這樣做。

如果放棄使用枚舉,也許聲明它們爲正常類,那麼你可以自由地做它與其他事物一樣,如

class VolumeUnit extends AbstractUnit { 
    public static final VolumeUnit CUBIC_METER = new VolumeUnit(params); 
    .. 

    VolumeUnit(..) { 
    .. 
    } 
} 
+0

我看到了,我應該添加一個參數化屬性來存儲基本類型值(CUBIC_METER,KILOGRAM)? – user1713042