正确设计Java类

时间:2014-11-19 19:17:56

标签: java class variables object private

假设我有类药物安装:

package core;

public abstract class DrugAmount {

    boolean drugInMg = false;
    boolean drugInMl = false;
    double numberofAmpoules = 0.0;
    double ampoulesInML = 0.0;
    double ampoulesInMG = 0.0;

    public DrugAmount() {
    }

    public DrugAmount(int numberOfAmpoules) {
        setNumberofAmpoules(numberOfAmpoules);
    }

    // SETTER:

    private void setNumberofAmpoules(int numberOfAmpoules) {
        this.numberofAmpoules = numberOfAmpoules;
    }

    // GETTER:

    public double getNumberOfAmpoules() {
        return numberofAmpoules;
    }

    public double getAmpoulesInML() {
        return ampoulesInML;
    }

    public double getAmpoulesInMG() {
        return ampoulesInMG;
    }

    public boolean isDrugInMl() {
        return drugInMl;
    }

    public boolean isDrugInMg() {
        return drugInMg;
    }

}

和DrugAmountMg类:

package core;

public class DrugAmountMg extends DrugAmount {

    public DrugAmountMg(double drugAmount) {
        super();
        setDrugInMg();
        setAmpoulesMG(drugAmount);
        setNumberOfAmpoules();
        turnDrugFromMgToMl();
    }

    public DrugAmountMg(int drugAmount) {
        super(drugAmount);
        setDrugInMg();
        setAmpoulesMG();
        turnDrugFromMgToMl();
    }

    private void setNumberOfAmpoules() {
        numberofAmpoules = ((1 / Ampoule.AMOUNT_OF_ONE_AMPOULE_IN_MG) * getAmpoulesInMG());
    }

    private void setAmpoulesMG() {
        ampoulesInMG=(Ampoule.AMOUNT_OF_ONE_AMPOULE_IN_MG*getNumberOfAmpoules());
    }

    private void setAmpoulesMG(double drugAmount) {
        ampoulesInMG=drugAmount;
    }

    private void turnDrugFromMgToMl() {
        if (isDrugInMg()) {
            ampoulesInML=(Ampoule.AMOUNT_OF_ONE_AMPOULE_IN_ML / Ampoule.AMOUNT_OF_ONE_AMPOULE_IN_MG) * getAmpoulesInMG();
        }
    }

    private void setDrugInMg() {
        drugInMg = true;
    }
}

就像你可以看到DrugAmount类中有“package private”对象变量 - 这是一个很好的java实践吗?

或者我应该将它们修改为private并在子类DrugAmountMg中声明新的对象变量,并通过getter-methods为它们分配DrugAmount变量的值?

1 个答案:

答案 0 :(得分:1)

您可以保留原样,但是您真的需要从同一个包中不是子类的其他类访问它们吗?我会在基类中创建它们protected

你绝对应该在子类中声明新字段。然后该类将具有每个字段中的两个(例如,drugInMg),即使其中只有一个将在子类的源代码中的范围内,如果您要使用它,则可能会遇到麻烦尝试通过反射设置私有字段,例如在单元测试中。在我正在研究的项目中,我们偶尔遇到问题,其中一个类具有相同类型和字段的字段,在类层次结构中的不同点处声明为私有字段,以及使用反射实用程序的单元测试设置私有字段失败,因为他们设置错误。

我不确定你的意思"通过getter-methods"为他们分配DrugAmount变量的值。我怀疑你的意思是你要在基类中创建字段私有,创建getter,复制子类中的字段,并从基类中获取值来设置子类?再次,以这种方式复制字段是一个坏主意。

您可以做的另一件事是在基类中将字段设为私有,并提供getter 和setters 以允许子类更新字段,但这会使外部人员调用setter方法。您可以使setter受保护或package-private,但为什么不让实际字段受到保护?然后只有子类可以访问它们。