Java course

Use objects as fields: composition

1.7.3 — Use objects as fields: composition

Composition means using an object as part of another object. For example, a Booking can hold a reference to a Participant. This is a has-a relationship.

A class describes an object, new creates it, a field stores a value, and a method performs an action or returns a value. A private field is accessed through the class’s methods.

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.

Store the participant reference

The Booking constructor receives a Participant reference and stores it in its participant field. getParticipantName calls getName on that object.

this.participant is the field; the constructor parameter participant supplies its starting reference. final prevents replacing that field after construction.

Let the contained object do its work

The Participant label method formats the name. Booking.label calls that method instead of copying its formatting code. This is delegation: one object asks another to do the work.

If the participant’s label format changes, Booking can still call the same method.

Two containing objects can share one object

Passing the same reference to two constructors does not copy the Participant. Both bookings refer to the same Participant object.

Renaming that participant changes the name read through both bookings. A private field hides the field itself; it does not prevent changes through another reference to the shared object.

Create separate objects when you need separate state

Here each booking receives a different Participant object. Renaming the first participant leaves the second one unchanged.

Composition describes how objects are used together. It does not by itself decide whether references are shared; your new expressions and constructor arguments determine that.

Require an actual object

A field can hold null, which means no object. Calling getName through null would fail. The next constructor rejects null before storing the reference.

throw reports the invalid argument; catch prints its message. Checking this at construction gives a clearer failure than waiting for a later method call.

Choose the contained behavior through an interface

An interface declares methods its implementations provide. NameSource requires name(). PlainName returns its stored spelling; UpperName returns uppercase text.

Booking stores a NameSource reference and calls name on it. Both implementations work without changing Booking or duplicating its label code.

A Booking has a NameSource; it does not extend NameSource. extends would describe inheritance, rather than storing and using another object.

Practice: read the name from the field

Booking.getParticipantName currently returns Unknown instead of reading the Participant. Replace return "Unknown"; with return participant.getName();.

Leave main and Participant unchanged. The completed cell should print Ada.

Hint

Use the participant field to call getName. Return that method’s result directly.

Worked solution
public class PracticeComposition {
    public static void main(String[] args) {
        Booking booking = new Booking(new Participant("Ada"));
        System.out.println(booking.getParticipantName());
    }
}

class Participant {
    private String name;

    Participant(String name) {
        this.name = name;
    }

    String getName() {
        return name;
    }

    void rename(String name) {
        this.name = name;
    }
}

class Booking {
    private final Participant participant;

    Booking(Participant participant) {
        this.participant = participant;
    }

    String getParticipantName() {
        return participant.getName();
    }
}

Try other names

In your completed cell, change only the text inside new Participant:

Constructor callExpected output
new Participant("Ada")Ada
new Participant("Ben")Ben
new Participant("Cleo")Cleo

Keep Booking unchanged. Its method works with the object it receives.

Enable JavaScript to run the Java notebook.