-1

starting some new stuff in Java and im kind of having a hard time. I feel like im on the right track just for some reason cannot find a way around the problem I am having without violating encapsulation. I have these two classes called Weight and Project. I have finished both of them but get errors in the Project class. Which include, 'toOunces', 'ounces', and 'OUNCES_IN_A_POUND'. these are private in the Weight class. I already understand that I cannot carry over private variables, methods, ect. from one class to another. I just have no clue how to go about this without violating encapsulation. below i have both the Weight class and the Project class as well as the assignment details.

I am not looking for anyone to do the work for me as I am just looking for tips, tricks, and suggestions. Also please bear with me as I am still learning the Java language and on the first week of 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());
    }
}

link to the PDF file for the assignment details: https://learn.umgc.edu/d2l/common/viewFile.d2lfile/Database/NzQ5OTk1NjE/Assignment1.pdf?ou=1016228

Oquin123
  • 9
  • 1
  • 1
    You could add a static sum method to the Weight class that takes Weights and returns the sum as a Weight. – Hulk May 31 '23 at 19:58
  • 1
    You could return `new Weight(0, averageOunces)` from the `findAverage()` method. – Thomas Kläger May 31 '23 at 20:13
  • The link to the assignment isn’t accessible. Stack Overflow questions should aim to be self-contained, so please copy the assignment text into the question (if that doesn’t violate academic policy) – Tim Moore Jun 01 '23 at 00:14
  • In general, the way you avoid violating encapsulation is by adding functionality to the encapsulated class. You could add a method to `Weight` that averages itself with another `Weight`. You can average three weights by taking the average of the first two, and then averaging that with the third. I don’t know if that’s what the instructor wants, though. – Tim Moore Jun 01 '23 at 00:18
  • Typically, when resolve is required from an alternate source you would create an _[accessor](https://docs.oracle.com/javase/tutorial/java/javaOO/variables.html)_ method. So in this case, _"getPoundsPerOunce"_, and _"getToOunces"_. If this appears to be typical for your design pattern, you could try creating an _[interface](https://docs.oracle.com/javase/tutorial/java/concepts/interface.html)_ or _[abstract class](https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html)_, for which you can more easily maintain what data is for local use, and what is for an alternate source. – Reilas Jun 01 '23 at 01:04
  • @Reilas Neither of those is correct. `toOunces()` is correct as it is, because it’s not a property of a Weight instance, it’s operation that’s performed on a Weight instance. Pounds per ounce is not a property of any one Weight instance, so it should be static. The correct solution here is either a static `sum` method like Hulk suggested, or a non-static `add` or `plus` method that takes one Weight argument and returns a new Weight instance. – VGR Jun 01 '23 at 12:58

1 Answers1

0

OUNCES_IN_A_POUND is private and should remain private. This is why the Project class cannot access it.

You are on the right track: this is indeed a matter of encapsulation. What you want to do is encapsulate all mathematical operations, inside public methods of the Weight class itself.

So, instead of this:

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;

You want to write something like this:

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

return sum.divideBy(3);

This achieves encapsulation by having the Weight class manage all computational operations. Callers never need to break the encapsulation by manipulating its numeric properties directly.

As you can see, a couple additions to Weight are needed:

/**
 * 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) {
    // ...
}

I leave it to you to implement that constructor and that method.

As a final note, you may want to consider renaming your addTo method to just add. The method is not adding anything to the argument and is not altering the argument in any way; rather, it is using the argument to add to the instance’s own value.

VGR
  • 40,506
  • 4
  • 48
  • 63