Stage 1 of 10 · 8 lessons · ~3 weeks
Object-oriented programming properly
Go beyond the textbook definitions: use classes to protect rules, interfaces to hide change, polymorphism to remove type checks and composition instead of deep inheritance, in your language's modern style.
Start: Classes, objects and responsibilitiesLessons· one lesson for each topic, in this order
- 1Classes, objects and responsibilitiesLesson
- 2Encapsulation and invariantsLesson
- 3Abstraction and interfacesLesson
- 4Inheritance, used sparinglyLesson
- 5Polymorphism instead of type checksLesson
- 6Composition over inheritanceLesson
- 7Value objects and immutabilityOptionalLesson
- 8Modern Java: records, sealed types and interfacesLesson
Do this
- Rewrite one old project class so that all fields are private and every rule is enforced in a method.
- Replace one if or switch on a type field with an interface and two classes.
- Refactor one inheritance you wrote for code reuse into composition.
- Write a small immutable value type, such as Money or Email, with its own validation.
- Write unit tests that prove your invariants cannot be broken from outside.
Start with· follow one of these
- CoursePaidGrokking the Object Oriented Design Interview
Design Gurus · Intermediate · Subscription
Its opening chapters teach the four OOP ideas applied inside real designs, with UML and running code
- CourseFreeMIT 6.102: Software Construction
MIT · Intermediate
Free MIT readings: Abstract Data Types, Rep Invariants and Interfaces and Subtyping are this stage at university depth
Practise
Keep handy
Also worth your time
Before moving on: A small domain model you wrote from a one-paragraph brief, such as a library or a clinic, with private state, at least one interface with two implementations, no type switches and composition wherever inheritance was tempting, plus unit tests for its rules.

Learn OOP on modern Java, not the Java of old textbooks: records, sealed interfaces and lambdas remove most boilerplate. Every class should protect a rule or hide a decision, and a getter and setter pair for every field protects nothing.