IS-A, HAS-A and Object Lifetime
Association, aggregation and composition: who owns whom, and what still exists when the owner is gone.
Open this lesson in the learning hubKey points
- IS-A is inheritance; HAS-A is a field. Most real models are almost all HAS-A with very little inheritance.
- Composition: the whole creates and owns the part. Drop the order and its lines go with it, because nothing else held them.
- Aggregation: the whole holds a part it did not create. Drop the order and the customer carries on existing.
- Association: it simply uses another object, usually one handed to a method, and keeps no field for it at all.
- Choose by lifetime: if the part cannot outlive the whole, build it inside; otherwise take it through the constructor.
- Keep an owned collection
privateand never hand it back raw, or the ownership you just modelled leaks away.
Example
import java.util.ArrayList;
import java.util.List;
public class Main {
record Customer(String name) { }
interface Printer { String render(String who, int cents); }
static final class Order {
// COMPOSITION: the Order creates its lines and nobody else can hold them.
private final List<Line> lines = new ArrayList<>();
// AGGREGATION: the customer is passed in and outlives this order.
private final Customer customer;
Order(Customer customer) { this.customer = customer; }
void add(String item, int cents) { lines.add(new Line(item, cents)); }
int total() {
int sum = 0;
for (Line line : lines) sum += line.cents();
return sum;
}
// ASSOCIATION: it uses a Printer for one call and keeps no field for it.
String print(Printer printer) { return printer.render(customer.name(), total()); }
record Line(String item, int cents) { }
}
public static void main(String[] args) {
Customer ada = new Customer("Ada");
Order order = new Order(ada);
order.add("keyboard", 4500);
order.add("cable", 900);
System.out.println(order.print((who, cents) -> who + " owes " + cents + " cents"));
// The order owns its lines: no caller can reach them or share them.
// The customer is only referenced, so she outlives every order.
System.out.println("customer still here: " + ada);
}
}
Model the relationship by lifetime and ownership, not by what is quickest to type.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the OOP course, and every lesson in it is listed on the OOP contents page.