6) Inheritance & Polymorphism (and when not to use them)
Goal
Learn how inheritance works, how polymorphism enables flexible code, and why composition is often a better default.
Inheritance basics
class Animal {
void speak() {
System.out.println("...");
}
}
class Dog extends Animal {
@Override
void speak() {
System.out.println("woof");
}
}
Polymorphism
Animal a = new Dog();
a.speak(); // woof
Your code can depend on the base type (Animal) and still work with any subclass.
When inheritance is risky
Inheritance can cause:
- tight coupling
- fragile base class problems
- confusing hierarchies
Prefer composition when possible: “has-a” over “is-a”.
Exercises
- Create
Shape with subclasses Circle and Rectangle and a method area().
- Replace inheritance with composition in one example: create a
Logger field used by another class.
Table of contents
- Getting Started: Install, run, and your first program
- Java Basics: types, variables, operators, formatting
- Control Flow: if/switch/loops
- Methods: parameters, return values, overloading
- OOP: classes, objects, encapsulation
- Inheritance & Polymorphism (and when not to use them)
- Interfaces, abstract classes, and design basics
- Exceptions and error handling
- Strings, files, and I/O basics
- Collections: List/Set/Map and Big-O intuition
- Generics (the useful parts)
- Lambdas & Streams
- Dates and time (java.time)
- Testing with JUnit 5 (basics)
- Concurrency: threads, executors, futures
- JVM basics: memory, GC, performance habits
- Build tools: Maven essentials (recommended)
- Next steps: projects to build