Build a calculator with methods and objects
1.8.1 — Build a calculator with methods and objects
This lesson builds a small calculator: divide a cost among participants and add participant counts. The inputs and rules are provided here.
long stores whole numbers, including amounts in cents. int stores participant counts. A method returns a result with return. A class stores related values; new creates an object.
Each code cell is a complete program with its own classes and inputs. Java starts in main; the statements inside its braces run in order. The other class declarations describe the objects used by main. Run each cell as a whole.
Define the inputs and expected results
Use whole cents so amounts such as 10.01 are represented exactly as 1001.
| Input | Example | Rule |
|---|---|---|
| Total cost in cents | 1001 | Must be at least 0 |
| Number of participants | 4 | Must be at least 1 |
| Attendance counts | {2, 3, 0} | Each count must be at least 0 |
The report needs the share per person, the remaining cents, and the attendance total.
Plan three steps: validate the inputs, calculate the results, then print them. An empty attendance array has total 0.
Calculate a share and a remainder
Integer division / gives a whole-number share. % gives the cents left over. For 1001 cents and 4 people, each share is 250 cents and 1 cent remains.
The methods below return these results. They check the arguments before dividing. || means or: either invalid condition is enough to reject the inputs.
Store one calculation’s inputs in an object
The CostSplit constructor validates the inputs and stores them in private fields. Each object keeps its own totalCents and people.
The fields are final: they are assigned during construction and cannot be reassigned afterward. shareCents and remainderCents use those stored values, so calls do not need the arguments again.
Add attendance counts
int[] is an array of whole numbers. The enhanced for loop reads each count. The total starts at zero; each repetition adds one count.
A negative count is rejected. For an empty array, the loop runs zero times and returns 0. The long total can hold a sum larger than a single int.
Put the results together
Keep calculation separate from printing. CostSplit calculates the share; attendanceTotal calculates attendance; main prints their results.
Both pieces are included in this cell. The CostSplit people value describes one cost split; the attendance array records separate counts. They are separate inputs, so they do not have to add to the same number.
Check invalid inputs without stopping the report
Use try/catch around an operation that may reject its inputs. After catch prints the problem, later statements can still run.
A split with zero people is invalid because there is nobody to receive a share. The next cell also checks that an attendance count cannot be negative.
Check small cases
The same rules should work with zero cost, one person, and fewer cents than people.
| Total cents | People | Share | Remainder |
|---|---|---|---|
| 0 | 4 | 0 | 0 |
| 7 | 1 | 7 | 0 |
| 2 | 5 | 0 | 2 |
The next cell checks the last row. Multiplying the share by people and adding the remainder reconstructs the original cost.
Practice: calculate the share
The next class incorrectly returns the whole cost as one person’s share. In shareCents, replace return totalCents; with return totalCents / people;.
Leave main and remainderCents unchanged. The completed cell should print Share: 250 and Remainder: 1.
Hint
Change only the return line inside shareCents. Use the object’s two fields in the division: totalCents / people.
Worked solution
public class PracticeCalculator {
public static void main(String[] args) {
CostSplit split = new CostSplit(1001, 4);
System.out.println("Share: " + split.shareCents());
System.out.println("Remainder: " + split.remainderCents());
}
}
class CostSplit {
private final long totalCents;
private final int people;
CostSplit(long totalCents, int people) {
if (totalCents < 0 || people <= 0) {
throw new IllegalArgumentException("Cost must be nonnegative and people must be positive");
}
this.totalCents = totalCents;
this.people = people;
}
long shareCents() {
return totalCents / people;
}
long remainderCents() {
return totalCents % people;
}
}Try other inputs
In your completed cell, change only the two arguments to new CostSplit:
| Constructor call | Share | Remainder |
|---|---|---|
new CostSplit(0, 4) | 0 | 0 |
new CostSplit(7, 1) | 7 | 0 |
new CostSplit(2, 5) | 0 | 2 |
new CostSplit(1001, 4) | 250 | 1 |
These calls test different inputs with the same implementation.
Enable JavaScript to run the Java notebook.