Skip to content
Home/Resources/Data Structures and Algorithms/Object-oriented programming explained
Explainer ยท Data Structures and Algorithms

Object-Oriented Programming (OOP) Explained: Classes, Objects and the Four Pillars With Examples

By Younus FardeenUpdated 4 Nov 20264 min read
Short answer

Object-oriented programming (OOP) organises code into objects that bundle data (attributes) with the functions that work on it (methods), created from blueprints called classes. Its four pillars are encapsulation (hide internal data), abstraction (expose only what is needed), inheritance (reuse behaviour from a parent class) and polymorphism (one interface, many behaviours).

OOP is how most large programs in Java, Python, C# and JavaScript are organised. The ideas are small. What takes practice is deciding what should be a class.

Classes and objects

A class is a blueprint, such as a bank account with an owner and a balance. An object is one real account made from that blueprint. An attribute is a piece of data on the object and a method is something it can do.

class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self._balance = balance            # underscore: "please do not touch directly"

    def deposit(self, amount):
        if amount <= 0:
            raise ValueError("Deposit must be positive")
        self._balance += amount

    def withdraw(self, amount):
        if amount > self._balance:
            raise ValueError("Insufficient funds")
        self._balance -= amount

    @property
    def balance(self):
        return self._balance

class SavingsAccount(BankAccount):           # inheritance
    def __init__(self, owner, balance=0, rate=0.04):
        super().__init__(owner, balance)
        self.rate = rate

    def add_interest(self):
        self.deposit(self._balance * self.rate)

account = SavingsAccount("Asha", 1000)
account.deposit(500)
account.add_interest()
print(account.balance)

Output: 1560.0. The account holds 1000, receives a 500 deposit, then earns 4% interest.

The four pillars of OOP

PillarMeaningIn the example
EncapsulationKeep data inside the object and control access through methods_balance is changed only through deposit and withdraw, which check the rules
AbstractionShow what an object does, hide how it does itCallers use deposit() without knowing how the balance is stored
InheritanceA child class reuses and extends a parent classSavingsAccount extends BankAccount and adds interest
PolymorphismThe same call behaves differently for different typesshape.area() works for any shape

Polymorphism in Python

class Shape:
    def area(self):
        raise NotImplementedError

class Circle(Shape):
    def __init__(self, r):
        self.r = r
    def area(self):
        return round(3.14159 * self.r ** 2, 2)

class Rectangle(Shape):
    def __init__(self, w, h):
        self.w, self.h = w, h
    def area(self):
        return self.w * self.h

for shape in [Circle(2), Rectangle(3, 4)]:     # same call, different behaviour
    print(type(shape).__name__, shape.area())

Output: Circle 12.57 and Rectangle 12

Inheritance in JavaScript

class Animal {
  constructor(name) { this.name = name; }
  speak() { return `${this.name} makes a sound`; }
}
class Dog extends Animal {
  speak() { return `${this.name} barks`; }
}
for (const a of [new Animal("Generic"), new Dog("Bruno")]) console.log(a.speak());

Output: Generic makes a sound and Bruno barks

All four ideas in Java

abstract class Shape {
    abstract double area();                 // abstraction: what, not how
}

class Rectangle extends Shape {              // inheritance
    private final double width, height;      // encapsulation: private fields
    Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    @Override
    double area() { return width * height; } // polymorphism: overriding
}

public class Main {
    public static void main(String[] args) {
        Shape shape = new Rectangle(3, 4);
        System.out.println(shape.area());    // 12.0
    }
}

OOP vs procedural vs functional

StyleOrganises code aroundGood for
ProceduralFunctions that act on shared dataScripts, small programs
Object-orientedObjects that own their data and behaviourLarge systems with many related entities
FunctionalPure functions and immutable dataData pipelines, concurrency

Modern code mixes the styles. A useful rule is to prefer composition (an object has another object) over deep inheritance trees (an object is another object).

Frequently asked OOP interview questions

  • What is the difference between a class and an object?
  • What is the difference between an abstract class and an interface?
  • What is the difference between method overloading and overriding?
  • What is encapsulation, and how do you achieve it?
  • Why is multiple inheritance a problem (the diamond problem)?
  • What does a constructor do?
  • When would you choose composition over inheritance?

Common mistakes

  • Making everything public, so any code can break the object's rules.
  • Deep inheritance chains that are hard to follow, where composition would be simpler.
  • Classes that do too many jobs. Give each class one clear responsibility.
  • Using inheritance only to share code instead of modelling an "is a" relationship.

Build something to make it stick

  • A library management system: books, members, loans.
  • A parking lot with vehicle types and slot allocation.
  • An ATM with accounts and transaction rules.
  • A text-adventure game with rooms, items and characters.

Add tests for each class, then put them on GitHub. See the software projects and the Masai guide to introduction to object-oriented programming.

Frequently asked questions

What is OOP in simple words?

A way of writing programs as a set of objects, each holding its own data and the actions it can perform, built from classes.

What are the four pillars of OOP?

Encapsulation, abstraction, inheritance and polymorphism.

What is the difference between a class and an object?

A class is the blueprint. An object is an instance created from that blueprint, with its own values.

Which languages use OOP?

Java, C#, C++, Python, JavaScript, Kotlin, Swift and Ruby all support it.

Is OOP still relevant with functional programming?

Yes. Most production codebases in Java, Python and C# are object-oriented, and many mix in functional ideas.

Learn this with mentors

Programmes for builders and engineers with admissions open: live classes, mentors and project work.

Continue learning

Learning path

Data Structures and Algorithms learning path

Arrays to dynamic programming in order, with a problem plan.

Explainer

Java syntax basics

Program structure, types, loops, methods and common errors.

Open →
Explainer

HashMap explained

How hashing, buckets and collisions work, with Python, JS and Java.

Open →