尽量避免违反封装

trying to avoid violating encapsulation

提问人:Oquin123 提问时间:6/1/2023 更新时间:6/1/2023 访问量:47

问:

在 Java 中开始一些新东西,我有点困难。我觉得我走在正确的轨道上,只是出于某种原因,无法在不违反封装的情况下找到解决我所遇到的问题的方法。我有这两个类,分别称为 Weight 和 Project。我已经完成了这两个任务,但在 Project 类中出现错误。其中包括“toOunces”、“ounces”和“OUNCES_IN_A_POUND”。这些在 Weight 类中是私有的。我已经明白我不能继承私有变量、方法等。从一个班级到另一个班级。我只是不知道如何在不违反封装的情况下解决这个问题。下面我有 Weight 类和 Project 类以及作业详细信息。

我不是在寻找任何人为我做这项工作,因为我只是在寻找技巧、窍门和建议。另外,请耐心等待,因为我仍在学习 Java 语言,并且在 CMIS 242 的第一周。

public class Weight {

    //Private variables
    private static final int OUNCES_IN_A_POUND = 16;
    private int pounds;
    private double ounces;

    //A public parameterized constructor, which initializes the private variables.
    public Weight(int pounds, double ounces) {
        this.pounds = pounds;
        this.ounces = ounces;
        normalize();
    }

    //instance methods
    private double toOunces() {
        return (pounds * OUNCES_IN_A_POUND) + ounces;
    }

    private void normalize() {
        while (ounces >= OUNCES_IN_A_POUND) {
            pounds++;
            ounces -= OUNCES_IN_A_POUND;
        }
    }

    public boolean lessThan(Weight weight) {
        double thisOunces = toOunces();
        double otherOunces = weight.toOunces();
        return thisOunces < otherOunces;
    }

    public void addTo(Weight weight) {
        double thisOunces = toOunces();
        double otherOunces = weight.toOunces();
        double totalOunces = thisOunces + otherOunces;

        pounds = (int) (totalOunces / OUNCES_IN_A_POUND);
        ounces = totalOunces % OUNCES_IN_A_POUND;
        normalize();
    }

    public String toString() {
        return pounds + " pounds and " + String.format("%.2f", ounces) + " ounces";
    }
}

----------------------------------------------------------------------------------------------------
public class Project {
    private static Weight findMinimum(Weight weight1, Weight weight2, Weight weight3) {
        Weight minimumWeight = weight1;

        if (weight2.lessThan(minimumWeight)) {
            minimumWeight = weight2;
        }

        if (weight3.lessThan(minimumWeight)) {
            minimumWeight = weight3;
        }

        return minimumWeight;
    }

    private static Weight findMaximum(Weight weight1, Weight weight2, Weight weight3) {
        Weight maximumWeight = weight1;

        if (weight2.toOunces() > maximumWeight.toOunces()) {
            maximumWeight = weight2;
        }

        if (weight3.toOunces() > maximumWeight.toOunces()) {
            maximumWeight = weight3;
        }

        return maximumWeight;
    }

    private static Weight findAverage(Weight weight1, Weight weight2, Weight weight3) {
        double totalOunces = weight1.toOunces() + weight2.toOunces() + weight3.toOunces();
        double averageOunces = totalOunces / 3.0;

        int averagePounds = (int) (averageOunces / Weight.OUNCES_IN_A_POUND);
        double averageOuncesRemaining = averageOunces % Weight.OUNCES_IN_A_POUND;

        return new Weight(averagePounds, averageOuncesRemaining);
    }


    public static void main(String[] args) {
        //instances of the weight class
        Weight weight1 = new Weight(11, 3);
        Weight weight2 = new Weight(7, 20);
        Weight weight3 = new Weight(14, 6);

        System.out.println("Weight 1: " + weight1.toString());
        System.out.println("Weight 2: " + weight2.toString());
        System.out.println("Weight 3: " + weight3.toString());

        Weight minimumWeight = findMinimum(weight1, weight2, weight3);
        System.out.println("The minimum weight is " + minimumWeight.toString());

        Weight maximumWeight = findMaximum(weight1, weight2, weight3);
        System.out.println("The maximum weight is " + maximumWeight.toString());

        Weight averageWeight = findAverage(weight1, weight2, weight3);
        System.out.println("The average weight is " + averageWeight.toString());
    }
}

作业详情的 PDF 文件链接:https://learn.umgc.edu/d2l/common/viewFile.d2lfile/Database/NzQ5OTk1NjE/Assignment1.pdf?ou=1016228

Java 封装 私有方法

评论

1赞 Hulk 6/1/2023
可以向 Weight 类添加一个静态 sum 方法,该方法采用 Weights 并将总和作为 Weight 返回。
1赞 Thomas Kläger 6/1/2023
您可以从该方法返回。new Weight(0, averageOunces)findAverage()
0赞 Tim Moore 6/1/2023
无法访问指向作业的链接。Stack Overflow 问题应以独立为目标,因此请将作业文本复制到问题中(如果这不违反学术政策)
0赞 Tim Moore 6/1/2023
通常,避免违反封装的方法是向封装类添加功能。您可以添加一个方法,该方法将自身与另一个方法平均。您可以通过取前两个权重的平均值,然后用第三个权重取平均值来平均三个权重。不过,我不知道这是否是教练想要的。WeightWeight
0赞 Reilas 6/1/2023
通常,当需要从备用源进行解析时,您将创建一个访问器方法。因此,在本例中,“getPoundsPerOunce”“getToOunces”。如果这似乎是您的设计模式的典型特征,您可以尝试创建一个接口抽象类,以便更轻松地维护哪些数据供本地使用,哪些数据供备用源使用。

答:

0赞 VGR 6/1/2023 #1

OUNCES_IN_A_POUND是私有的,应保持私密。这就是 Project 类无法访问它的原因。

你走在正确的轨道上:这确实是一个封装问题。您要做的是将所有数学运算封装在 Weight 类本身的公共方法中。

所以,而不是这个:

double totalOunces = weight1.toOunces() + weight2.toOunces() + weight3.toOunces();
double averageOunces = totalOunces / 3.0;

int averagePounds = (int) (averageOunces / Weight.OUNCES_IN_A_POUND);
double averageOuncesRemaining = averageOunces % Weight.OUNCES_IN_A_POUND;

你想写这样的东西:

Weight sum = new Weight(weight1);
sum.addTo(weight2);
sum.addTo(weight3);

return sum.divideBy(3);

这通过让 Weight 类管理所有计算操作来实现封装。调用方永远不需要通过直接操作其数值属性来破坏封装。

正如你所看到的,需要对权重进行一些补充:

/**
 * Makes a copy of an existing Weight instance.
 *
 * @param other non-null Weight instance to be copied
 */
public Weight(Weight other) {
    // ...
}

/**
 * Divides this Weight by the given factor.
 *
 * @param divisor amount by which this Weight will be divided
 */
public void divideBy(double divisor) {
    // ...
}

我把它留给你来实现那个构造函数和那个方法。

最后,您可能需要考虑将方法重命名为 .该方法不会向参数添加任何内容,也不会以任何方式更改参数;相反,它使用参数来增加实例自身的值。addToadd