← Skill tree CS Skill Tree 0 CSCD210

Writing a Class: Fields, Constructors, and Encapsulation

Textbook: BJP (Reges and Stepp)

Where you are: Week 0 review > Writing a class

Try This First

A Book class exposes its price as a public field, so any code can write book.price = -5;. Name the problem this creates before reading on.

Reveal

Nothing stops an invalid value. A public field has no gatekeeper, so a Book can hold a negative price. Making the field private and writing through a validating setter keeps every Book in a valid state.

Before You Start

Check each box you can do from memory. A box you cannot check yet is not a problem; it points you to a quick refresher, not a grade.

The Method Header and How a Method Works

Not sure? Take the 60-second self-check.

Try each from memory, then read the answer under it.

  1. A constructor, a getter, and a setter are all what? Methods, so the header rules (name, parameters, return type) apply to them.
  2. What does the return type void mean? The method hands nothing back; it does its work and returns.

What You Need To Walk In With

Walk into the next class able to state these:

You should be able to: write a class with private fields, a validating constructor, getters and setters, and a toString.

How It Works

public class Book {
    private final String title;   // final: no setter, set once at construction
    private double price;         // mutable: guarded by a setter

    public Book(String title, double price) {
        if (title == null || title.isBlank()) {
            throw new IllegalArgumentException("title must not be blank");
        }
        if (price < 0) {
            throw new IllegalArgumentException("price must be at least 0");
        }
        this.title = title;
        this.price = price;
    }

    public String getTitle() { return title; }
    public double getPrice() { return price; }

    public void setPrice(double price) {
        if (price < 0) {
            throw new IllegalArgumentException("price must be at least 0");
        }
        this.price = price;
    }

    @Override
    public String toString() {
        return String.format("Book[title=%s, price=%.2f]", title, price);
    }
}

Worked Example: Predict, Then Check

Book b = new Book("", 20.0);

Predict what happens when this line runs.

Reveal

It throws IllegalArgumentException with the message “title must not be blank”. The constructor’s if-throw rejects the blank title before the object is ever built, so no invalid Book exists.

A Common Mistake

Leaving fields public (or skipping the constructor checks) allows outside code to put an object into an invalid state, such as a negative price, with nothing to catch it. Make fields private, validate in the constructor and setters, and the class guarantees its own rules. (Source: BJP (Reges and Stepp), Ch 8; Effective Java, Item 16.)

Go Deeper (optional)

For the curious: marking a field final (like title) says it is set once at construction and never changes. A class whose fields are all final is immutable: once built, it cannot change, so it is always valid and safe to share. Many bugs disappear simply by making a field final and removing its setter.

Check Yourself

Close the notes and answer each one from memory, then reveal it. Pulling an idea back from memory is one of the strongest ways to make it stick.

Check your understanding

Why make a class field private?

Tier 1 · BJP (Reges and Stepp), Ch 8

What do the if-throw checks in a constructor guarantee?

Tier 2 · BJP (Reges and Stepp), Ch 8

Without a toString override, what does System.out.println(book) print?

Tier 2 · BJP (Reges and Stepp), Ch 8

What does the @Override annotation do?

Tier 1 · Effective Java, Item 40