You can design a class with an invariant, use an interface for substitution, and distinguish compile-time overloading from runtime overriding. Readiness: method parameters, return values, and object references.
A course catalog contains different content items that can all produce a display label. The caller should depend on a small capability, not each concrete class.
interface Labeled {
String label();
}
final class Course implements Labeled {
private final String code;
private final String title;
Course(String code, String title) {
if (code == null || code.isBlank()) throw new IllegalArgumentException("code");
this.code = code;
this.title = title;
}
public String label() { return code + " - " + title; }
public String label(boolean compact) { return compact ? code : label(); }
}
The two label methods are overloaded: same name, different parameter list, selected at compile time. Course.label() overrides the interface method and is selected through dynamic dispatch for a Labeled reference.
Private state plus validated construction keeps code nonblank. Encapsulation is not “add getters/setters for everything”; it protects valid state and exposes meaningful operations. Composition often gives more flexible reuse than inheritance.
Labeled item = new Course("DI-322", "Web Technologies"); item.label() calls which implementation? Hint: declared reference type provides the contract; runtime object supplies the override. Solution: Course.label().
static method is hidden, not overridden through instance dynamic dispatch.Build ContentItem with Lesson and Quiz implementations. Each has an ID and summary(). Add one meaningful overload, validate constructor state, store items in a List<ContentItem>, and print summaries polymorphically. Test blank IDs and two concrete types.
Q1 Method signature purpose? Distinguish callable methods by name/parameters. Q2 Class? Blueprint/type defining state and behavior. Q3 Interface? A capability contract. Q4 Overloading resolution? Compile time. Q5 Overriding dispatch? Runtime object. Q6 Main OOP repair? Model valid responsibilities, not merely add inheritance.
Design a notification component with email and in-app implementations behind one interface. Include failure representation, one invariant, a fake for testing, and a short composition-vs-inheritance justification. Rubric: contract 2, implementations 2, invariant/error 2, polymorphic use 2, reasoning/tests 2.
Method = named behavior; class = state + behavior + invariants; interface = substitutable capability. Overload chooses a signature; override chooses an implementation.