Handbooks / OOP & Design Patterns / Chapter 1

The Four Pillars of OOP

7 pages · ~5 min✓ Reviewed

Start here. Next up: SOLID Principles.

OOP & Design PatternsPage 1

Classes and Objects: The Mental Model

1. Class vs Object

  • Class = blueprint: state (fields) + behavior (methods)
  • Object = one instance, created at runtime
  • Constructor runs on creation to initialise state
  • No constructor defined → compiler adds a no-arg default
Instance fieldstatic member
Belongs toone objectthe class
Copiesone per objectone, shared

2. Example: Create and Call

java
Car c = new Car("red");
c.drive();

one object, method called through the reference c

3. Gotcha: Reference ≠ Object

java
Car a = new Car("red");
Car b = a;
b.color = "blue";
// a.color is now "blue"
  • b = a copies the reference, not the object
  • Both point to the same object
Remember

A variable holds a reference. Change through either name and both see it.

OOP & Design PatternsPage 2

Encapsulation and Abstraction

1. Encapsulation

  • Encapsulation = data plus the methods that act on it, in one class
  • Fields are private; outside code uses public methods
  • Getters/setters validate input and let internals change without breaking callers
java
private double balance;
public void deposit(double x) {
    if (x <= 0)
        throw new IllegalArgumentException();
    balance += x;
}

balance can never get a bad value

2. Abstraction vs Encapsulation

  • Abstraction = expose what an object does, hide how
  • Built with abstract class and interface
  • Model only the essential behavior
EncapsulationAbstraction
GoalProtect stateSimplify the design
IdeaInformation hidingEssential behavior only
Toolprivate fieldsabstract classes, interfaces

3. Common Mistake

  • Public getter returning the internal mutable list leaks state
Return a copy

Return List.copyOf(items) or Collections.unmodifiableList(items), never the raw list.

OOP & Design PatternsPage 3

Inheritance and the super Keyword

1. What Inheritance Is

  • Inheritance = subclass reuses and extends a superclass
  • Models is-a: a Dog is an Animal
  • Syntax: class Dog extends Animal
  • Subclass gets the non-private fields and methods

2. super and Single Inheritance

  • super(...) calls the parent constructor: first statement in the child constructor
  • super.method() calls the parent version of a method
  • Java allows one superclass only
  • Multiple behavior: implement several interfaces
java
class Dog extends Animal {
  Dog() { super("Rex"); }
  void speak() {
    super.speak();
  }
}

parent constructor first, then parent method

3. Abstract Class vs Interface

Abstract classInterface
Statefields + constructorsno instance state
Purposeshared base for related classescontract for unrelated classes
Inheritextends oneimplements many
Gotcha: final

final class cannot be extended; final method cannot be overridden.

OOP & Design PatternsPage 4

Polymorphism: Overloading vs Overriding

1. One Interface, Many Forms

  • Polymorphism = one call, behaviour depends on the object
  • Overloading: same name, different parameters, same class; compile time (static binding)
  • Overriding: subclass redefines inherited method, same signature; runtime (dynamic dispatch)

2. Example: Runtime Type Wins

java
class Animal { void speak() { print("..."); } }
class Dog extends Animal {
  @Override void speak() { print("Woof"); }
}
Animal a = new Dog();
a.speak();

runtime type decides, not the reference type

output
Woof

3. Overloading vs Overriding

OverloadingOverriding
Wheresame classsubclass
Signaturedifferent parameterssame signature
Boundcompile timeruntime
Return typealone cannot overloadsame or covariant
Accessanyno narrower than parent

4. Gotchas

  • static methods are hidden, not overridden
  • private and final methods cannot be overridden
Add @Override

A typo in the name or parameters becomes a compile error, not a silent new method.

OOP & Design PatternsPage 5

Composition vs Inheritance

1. Has-a vs Is-a

  • Composition = has-a: a field holds another object
  • Work is delegated to it (Car has an Engine)
InheritanceComposition
Relationis-ahas-a
Couplingtight, compile-timeloose
Swap at runtimenoyes

2. Example: Car has an Engine

  • Engine is passed in; start() delegates to it
java
class Car {
  private Engine engine;
  Car(Engine e) { this.engine = e; }
  void start() { engine.start(); }
}

3. Choosing and Mistakes

  • Inheriting only to reuse code: fragile base class, a parent change breaks every child
  • Deep hierarchies are hard to follow: keep them shallow
Default to composition

Type the field as an interface so the part can be swapped at runtime.

OOP & Design PatternsPage 6

OOP Cheat Sheet

1. Classes and Pillars

IdeaRemember
Classblueprint; object = one instance
staticshared by the class
Instanceone copy per object
Encapsulationprivate fields + public methods
Abstractionexpose what, hide how

2. Inheritance and Polymorphism

  • Inheritance = is-a, extends, super()
  • Reference type decides what you can call
  • Object type decides which override runs
OverridingOverloading
Signaturesame in the childsame name, different parameters
Resolvedruntimecompile time
java
Animal a = new Dog();
a.speak(); // Dog.speak() runs
a.fetch(); // compile error

Animal has no fetch()

3. Choosing

  • extends for is-a, composition for has-a
  • Default to composition
  • Use @Override and final deliberately
Remember

The reference type sets what you can call; the object type sets which override runs.

OOP & Design PatternsPage 7

Check yourself

Animal a = new Dog(); a.speak(); a.fetch(); Dog overrides speak and adds fetch. What happens?
  • a.speak() runs Dog's version: the object type picks the override
  • a.fetch() fails to compile: the reference type Animal has no fetch
After Car b = a; b.color = "blue";, what does a.color hold?
  • blue: b = a copies the reference, not the object
  • Both names point at one Car
A getter does return items; for a private list. Why is that still a leak?
  • Callers get the real list, so getItems().clear() empties your state
  • Return List.copyOf(items) or an unmodifiable view
Can int f(int x) overload void f(int x) in one class?
  • No: the parameter lists match, only the return type differs
  • Overloads need different parameters