Object-Oriented Programming concepts
Classes, objects, and the four pillars of OOP — encapsulation, abstraction, inheritance, and polymorphism — explained plainly, with when (and when not) to use them.
Classes and objects
Object-oriented programming (OOP) organizes code around objects — bundles of
data (state) and the functions that operate on it (behavior). A class is the
blueprint; an object is a concrete instance of it. A BankAccount
class might define a balance and methods like deposit() and
withdraw(); each open account is an object with its own balance.
The goal is to keep related state and behavior together, so the rest of your program talks to a small, well-defined surface instead of juggling loose variables. The four ideas below are how OOP delivers that.
1. Encapsulation
Encapsulation means bundling data with the methods that use it, and hiding the internals.
Callers go through a public interface (deposit()), not the raw fields. The class can
enforce its own rules — reject a negative deposit, keep balance consistent — because
nothing outside can reach in and corrupt its state. Practically: make fields private, expose
intent-revealing methods.
2. Abstraction
Abstraction is exposing what something does while hiding how it does it. You call
account.transfer(other, 100) without knowing whether it writes to a database, calls a
network service, or updates memory. Good abstractions let you change the implementation without
touching the callers. Encapsulation is the mechanism; abstraction is the design goal it serves.
3. Inheritance
Inheritance lets a class derive from another, reusing its state and behavior and
extending or overriding parts. A SavingsAccount can inherit from BankAccount
and add interest. It models an “is-a” relationship — a savings account is a bank account.
Use it sparingly. Deep inheritance trees are brittle, and a subclass is tightly coupled to its parent. The modern guidance is “favor composition over inheritance”: build behavior by combining small objects (a “has-a” relationship) rather than inheriting from a tall hierarchy.
4. Polymorphism
Polymorphism (“many forms”) means one interface, many implementations. If
Circle and Square both implement an area() method, code can loop
over a list of Shape and call area() on each without knowing the concrete
type. Add a new shape later and the loop doesn’t change. This is what makes OOP code extensible.
When OOP helps — and when it doesn’t
- Good fit: domains with clear entities and rules (orders, users, accounts), large codebases where boundaries matter, and frameworks built around objects.
- Poor fit: simple data transformations and pipelines, where a functional style (pure functions over plain data) is often clearer. Many modern languages mix both — use the tool that fits the problem rather than forcing everything into a class.
FAQ
What’s the difference between a class and an object?
A class is the definition (the blueprint); an object is a specific instance created from it, with its own state.
Are the four pillars language-specific?
No — encapsulation, abstraction, inheritance, and polymorphism appear across Java, C#, C++, Python, Ruby, and more, though each language expresses them differently.
Why “composition over inheritance”?
Inheritance couples a subclass tightly to its parent and gets fragile as hierarchies deepen. Composing small, focused objects is more flexible and easier to change.
Related
See multithreading & concurrency and memory leaks, or browse the full Reference and the tools menu.