Matheion

MA-JAVA0 · Module M

Midterm practice — PiggyBank class drill

Topics: Write a class · Constructor · Instance methods · Getters · main driver

Overview

Midterm practice — build a PiggyBank class

Before a typical midterm-style “write the class” question, practice the full loop on a fresh problem: private fields, a constructor, instance methods, getters, and a main that creates objects and calls methods.

Download the two starter files from the Worked code tab (PiggyBank.java and PiggyBankDemo.java). Fill in every TODO, compile, and match the expected output in the Concepts tab.

Time: about 60 minutes (longer if you type every line yourself).

Prerequisite sessions: 6–8 (classes, encapsulation, constructors).

Concepts

Your assignment — PiggyBank

Many midterm class-design tasks follow the same recipe:

  1. Private fields hold object state.
  2. A constructor initializes those fields.
  3. Instance methods change or read state through controlled methods (not raw field access from outside).
  4. main (in a separate driver file) creates objects with new and calls methods on each object.

This exercise uses a piggy bank — money in, money out — so you can focus on mechanics without memorizing a particular exam storyline.

Open the starter files from the Worked code tab. Complete every TODO in PiggyBank.java first, then PiggyBankDemo.java. Check your work against the test output below before opening Reveal.


Required class: PiggyBank

| Member | Requirement | |--------|-------------| | private String owner | Name on the label of this bank. | | private double balance | Dollars stored inside (never negative after construction rules). | | PiggyBank(String owner, double startingBalance) | Store owner. Store startingBalance as balance, unless startingBalance < 0, then store 0.0. | | void deposit(double amount) | If amount > 0, add to balance. Ignore non-positive amounts. | | boolean withdraw(double amount) | If amount > 0 and amount <= balance, subtract and return true. Otherwise return false without changing balance. | | double getBalance() | Return current balance (do not print here). | | String getOwner() | Return owner name. | | toString() (optional but recommended) | Return exactly two lines: owner: … then balance: … (use \\n between them). |

Storage rule: each PiggyBank object has its own fields. Two variables must not share one balance unless you deliberately assign an alias (not part of this exercise).


Required driver: PiggyBankDemo.main

After the class compiles, fill PiggyBankDemo.java:

  1. Create sam — owner "Sam", starting balance 10.0.
  2. Create alex — owner "Alex", starting balance 0.0.
  3. sam.deposit(5.0) then sam.deposit(3.0).
  4. Print sam.getOwner() + " has $" + sam.getBalance() → must show Sam has $18.0.
  5. Call sam.withdraw(20.0), store the boolean result, print whether withdrawal succeeded and Sam's balance after.
  6. alex.deposit(50.0), print Alex's owner and balance → Alex has $50.0.

Compile and run:

javac PiggyBank.java PiggyBankDemo.java
java PiggyBankDemo

Expected console output

Sam has $18.0
Withdrew $20? false
Sam now has $18.0
Alex has $50.0

If you implemented toString and used println(sam) in the optional step, you may also see:

owner: Sam
balance: 18.0
owner: Alex
balance: 50.0

Why each midterm skill appears here

| Skill | Where you use it | |-------|------------------| | Class vs object | PiggyBank is the blueprint; sam / alex are objects. | | Constructor | new PiggyBank("Sam", 10.0) runs the constructor once per object. | | this.field | Disambiguates parameters from fields when names match. | | Encapsulation | Fields private; outside code uses deposit, getBalance, etc. | | Instance method call | sam.deposit(5.0) — method on one object. | | Method return value | withdraw returns boolean; getBalance returns double. | | Separate driver | main lives in PiggyBankDemo, not inside the data class. |


Common mistakes

| Mistake | Fix | |---------|-----| | PiggyBank.deposit(5) without an object | Use sam.deposit(5.0). | | balance = amount in deposit | Add: balance = balance + amount. | | public double balance | Keep private; expose getBalance(). | | Forgetting new | PiggyBank sam = new PiggyBank(...). | | Printing inside getBalance() | Return the number; let main print. | | static balance shared by all banks | Each object gets its own instance fields. |

When stuck, read the Examples tab (tiny Greeter demo), then peek at Reveal only after you have a partial compile.

Examples

Example A — class, constructor, one method call

A minimal pattern repeated in almost every midterm class question:

public class Greeter {
    private String name;

    public Greeter(String name) {
        this.name = name;
    }

    public void sayHello() {
        System.out.println("Hello, " + name);
    }
}

Driver:

public class GreeterDemo {
    public static void main(String[] args) {
        Greeter g = new Greeter("Sam");
        g.sayHello();
    }
}

Read slowly:

  • Greeter = class (blueprint).
  • g = reference variable pointing at one object.
  • new Greeter("Sam") = allocate object + run constructor.
  • g.sayHello() = instance method call on that object.

Output: Hello, Sam


Example B — two objects, separate state

Greeter a = new Greeter("Ada");
Greeter b = new Greeter("Lin");
a.sayHello();
b.sayHello();

Each constructor call builds a different object with its own name. Changing one object never changes the other unless you deliberately alias references (Session 6).


Example C — getters instead of public fields

public class Counter {
    private int total;

    public Counter(int start) {
        this.total = start;
    }

    public void add(int n) {
        if (n > 0) {
            total = total + n;
        }
    }

    public int current() {
        return total;
    }
}

Usage:

Counter c = new Counter(0);
c.add(3);
c.add(5);
System.out.println(c.current()); // 8

PiggyBank.deposit follows the same “mutate private field through method” idea as Counter.add.


Example D — compile the starters

From the directory containing your downloaded files:

javac PiggyBank.java PiggyBankDemo.java

Fix the first compiler error before reading the rest — later errors often disappear after the root fix.

When PiggyBank.java is complete, PiggyBankDemo.java will compile once you replace TODO blocks with real statements.

Run:

java PiggyBankDemo

Compare output line by line with the Concepts tab expected transcript.

Bridge

After PiggyBank — midterm class questions

Once this drill compiles and prints the expected lines, you have rehearsed the core midterm class loop:

| Step | Exam habit | |------|------------| | Read the field list | Translate English spec → private fields | | Write constructor | this.field = parameter; defaults for flags | | Add getters/setters or behaviour methods | getX, setX, or deposit-style mutators | | Optional toString | Multi-line \\n block for println(obj) | | main elsewhere | Prompts, new, method calls, print results |

The names change on exam day (inventory item, sensor reading, account record). The shape stays the same.


Bridge to Session 7 Product pattern

Session 7 examples show a four-field class with constructor, getters/setters, and toString. PiggyBank is deliberately smaller:

  • Fewer fields (two instead of four).
  • One mutator pair (deposit / withdraw) instead of a setter per field.
  • Same private + main calling methods rule.

If PiggyBank felt shaky, retry only the constructor and one getter on paper before attempting a full four-field class from scratch.


Bridge to Session 10 — arrays of objects

Optional stretch after PiggyBank passes all tests:

PiggyBank[] club = new PiggyBank[2];
club[0] = new PiggyBank("Sam", 10.0);
club[1] = new PiggyBank("Alex", 0.0);

for (PiggyBank bank : club) {
    bank.deposit(1.0);
    System.out.println(bank);
}

Each array slot holds a reference to its own object — the same idea as an array of class instances in Session 10.

Practice check — midterm class drill

Multiple-choice check from the Matheion app lesson. Pick an answer for each question, then submit.

  1. 1.Why call `sam.deposit(5.0)` instead of `PiggyBank.deposit(5.0)`?

  2. 2.After `PiggyBank sam = new PiggyBank("Sam", 10.0);` and `PiggyBank alex = new PiggyBank("Alex", 0.0);`, sam deposits 8.0. What is alex.getBalance()?

  3. 3.Sam's balance is 18.0. withdraw(20.0) runs. What happens?

  4. 4.Why use getBalance() instead of making balance public?

  5. 5.What does `new PiggyBank("Alex", 0.0)` do?