2.2.5 · D1Design Principles

Foundations — SOLID — Open - Closed Principle

1,562 words7 min readBack to topic

Before you can feel why that works, you need the vocabulary the parent note throws around: class, method, interface / abstract class, polymorphism, switch/if-else chain, dependency. This page builds each one from nothing, in the order they stack on top of each other.


1. What is a class? (the blueprint)

Picture a cookie-cutter. The cutter itself is the class; each cookie it stamps is an object.

Figure — SOLID — Open - Closed Principle

In the parent's area example, Circle is a class. It remembers its radius r (data) and it knows how to compute its own area() (behaviour). Every actual circle you make — radius 2, radius 5 — is a separate object stamped from that one Circle blueprint.


2. What is a method? (a verb the object owns)

The . means "go into this object and run its verb." Think of area() as a button printed on the object; pressing it makes the object do work using its own remembered data.

Why does OCP care? Because the parent's whole game is "who owns the formula?" When area() lives inside Circle, the circle owns its own maths. Nobody outside needs to know how a circle computes area — they just press its button.


3. The if / elif (or switch) chain — the villain

Figure — SOLID — Open - Closed Principle

Look at the figure: one central area() method inspects shape.type and forks — circle here, rectangle there. It is a traffic cop standing at a junction, redirecting each type down its own lane.

The parent writes shape.type == "circle". The == here means "is it equal to?" — a yes/no test. Don't confuse it with the = that assigns a value. One asks, the other sets.


4. Inheritance — "is a kind of"

In Python you write class Circle(Shape): — the parentheses mean "Circle is a Shape."

Picture a family tree: Shape at the top, with Circle, Rectangle, Triangle hanging beneath it. They all are shapes, so they all promise to have an area().

Figure — SOLID — Open - Closed Principle

5. Abstract class / interface — the frozen contract

In the parent:

from abc import ABC, abstractmethod
class Shape(ABC):
    @abstractmethod
    def area(self): ...    # "every shape MUST have area() — but I won't say how"
  • ABC = Abstract Base Class (the "this is a contract" marker).
  • @abstractmethod = a sticky note saying "whoever inherits me must fill in this method or they can't exist."
  • ... = literally "left blank on purpose."

6. Polymorphism — one call, many behaviours

Figure — SOLID — Open - Closed Principle

Compare the two figures side by side in your head:

  • if/elif version (fig s02): the caller decides, via lanes, what maths to run.
  • Polymorphic version (fig s04): the object decides, because each object carries its own area(). The single call s.area() fans out automatically.

7. Dependency — "who needs to know about whom"


How these feed the topic

is cured by

Class - blueprint of data plus behaviour

Method - verb the object owns

if elif chain - the smell

Inheritance - is a kind of

Abstract class - frozen contract

Polymorphism - one call many behaviours

Dependency - who knows whom

Open Closed Principle


Equipment checklist

A class is
a blueprint bundling data (what it remembers) and behaviour (what it can do); objects are stamped from it.
A method is
a function that lives inside a class — a verb the object performs on itself, called with a dot.
The difference between == and =
== asks "are these equal?" (a yes/no test); = sets a value (assignment).
Why an if/elif chain on a type field is a smell
every new type forces you to re-open and edit that one working method — an OCP violation.
Inheritance means
a class declaring "I am a special kind of that other class," inheriting its data and behaviour.
An abstract class / interface is
a blueprint that declares required methods but leaves them blank — a frozen contract you inherit, not instantiate.
What @abstractmethod forces
any class inheriting it must fill in that method, or it cannot be created.
Polymorphism means
the same method call produces the right behaviour depending on which object receives it.
Polymorphism replaces which villain
the if/elif type-checking chain — each object now owns its own logic.
A dependency (A depends on B) means
A must know about B to work, so changing B can break A.
The OCP dependency flip
high-level code depends on the abstraction (interface), not on the concrete types.

Connections