PROGRAMMING-CONCEPTS

Object-Oriented Programming (OOP): Definition, Purpose, and Examples

Object-Oriented Programming (OOP) is a programming paradigm built around the idea of modeling software as a collection of objects—components that bundle data and behavior together. Instead of writing long procedural scripts, OOP encourages you to organize code into classes, objects, and reusable structures that mirror real-world concepts.

At its core, OOP helps you structure complex programs in a predictable, maintainable way. Classes describe what an object is, while objects represent specific instances that carry their own data. When used well, OOP simplifies large applications, supports collaboration, and makes code easier to extend without rewriting everything.


The Four Core Principles of OOP

OOP is based on four major ideas. These concepts appear across languages but take slightly different forms depending on syntax and features.

1. Encapsulation

Data and behavior are bundled together inside objects. A class exposes only what’s necessary and hides internal details.

2. Inheritance

A class can extend another class to reuse and customize behavior. This helps reduce duplication in systems that share a common structure.

3. Polymorphism

Objects can share an interface but behave differently depending on their type. This allows functions to operate on multiple kinds of objects seamlessly.

4. Abstraction

Complex implementation details are hidden behind simple, clear interfaces. This helps you think about what something does without worrying about how it works internally.


Classes and Objects in Action

A class defines the blueprint, and an object is the actual thing you create from it. Here is how different languages express that idea.

Python Example

class Product:
    def __init__(self, name, price):
        self.name = name
        self.price = price

    def apply_discount(self, percent):
        self.price *= (1 - percent / 100)

item = Product("Laptop", 1200)
item.apply_discount(10)

This defines a Product class that stores a name and price, and includes behavior to modify that price. The object item is a concrete instance, carrying its own state and able to run its method independently.


JavaScript / TypeScript Example

class Product {
  constructor(public name: string, public price: number) {}

  applyDiscount(percent: number) {
    this.price = this.price * (1 - percent / 100);
  }
}

const item = new Product("Laptop", 1200);
item.applyDiscount(10);

JavaScript and TypeScript implement classes that work similarly to Python's, but with optional type annotations in TypeScript. The this keyword refers to the specific instance stored in memory.


Swift Example

class Product {
    var name: String
    var price: Double

    init(name: String, price: Double) {
        self.name = name
        self.price = price
    }

    func applyDiscount(_ percent: Double) {
        price *= (1 - percent / 100)
    }
}

let item = Product(name: "Laptop", price: 1200)
item.applyDiscount(10)

Swift classes also bundle state and behavior, and create objects using init. Each instance stores its own copy of properties unless explicitly shared.


Inheritance and Method Overriding

Inheritance lets one class build on another, and overriding allows child classes to modify behaviors.

Python Example

class Product:
    def final_price(self):
        return 100

class DigitalProduct(Product):
    def final_price(self):
        return 100 * 0.9

Here, DigitalProduct inherits from Product but overrides the price logic. The program can treat both products the same while allowing each to behave differently when needed.


JavaScript Example

class Product {
  finalPrice() {
    return 100;
  }
}

class DigitalProduct extends Product {
  finalPrice() {
    return 100 * 0.9;
  }
}

JavaScript uses extends for inheritance and method overriding, using the same method name to customize behavior in subclasses.


Swift Example

class Product {
    func finalPrice() -> Double { 100 }
}

class DigitalProduct: Product {
    override func finalPrice() -> Double { 100 * 0.9 }
}

Swift uses override to clearly signal that a method intentionally replaces parent behavior. This prevents accidental overrides and adds clarity.


Polymorphism in Practice

Polymorphism allows code to treat different objects uniformly while letting each decide how to behave.

def print_price(item):
    print(item.final_price())

This function works with any object that has final_price(), not just one specific class. OOP encourages designing systems around shared capabilities rather than concrete types.


Encapsulation and Access Control

Different languages provide varying levels of access control to manage what parts of an object are exposed.

  • Python uses naming conventions like _internalValue
  • JavaScript/TypeScript use private, protected, public
  • Swift uses private, fileprivate, internal, public, open

The goal is the same: protect internal details so the rest of the program interacts with objects only through approved methods.

TypeScript Example

class BankAccount {
  private balance = 0;

  deposit(amount: number) {
    this.balance += amount;
  }
}

The balance property can't be accessed directly from outside the class, encouraging safe interactions through methods.


Composition vs Inheritance

OOP can reuse code through inheritance or composition. Composition often leads to cleaner designs that avoid deep inheritance chains.

function withLogging(obj) {
  return {
    ...obj,
    log() { console.log("Action performed"); }
  };
}

const user = withLogging({ name: "Sam" });

Here, instead of creating a subclass, the object gains new behavior by being composed with another object. This is a common pattern in modern JavaScript and React applications.


OOP in Real Applications

OOP appears everywhere across large programming ecosystems:

  • Web development: React components, Express.js route controllers, Django views
  • Mobile development: Swift and Kotlin UIs built around objects and models
  • Game development: Player, enemies, physics objects, scenes
  • Large codebases: Services, models, utilities organized into reusable classes

The paradigm makes it easier to scale features, collaborate across teams, and maintain clarity as systems grow.


When Not to Use OOP

While powerful, OOP isn’t always ideal.

Situations where alternatives work better:

  • Simple scripts or utilities (procedural programming is clearer)
  • Data transformations (functional programming is more concise)
  • Large inheritance hierarchies (hard to maintain over time)

Many modern systems use a mix of paradigms—Python, JavaScript, Swift, and React all support both OOP and functional styles.


Summary

Object-Oriented Programming is a structured approach to building software through objects that combine data and behavior. It uses classes, inheritance, polymorphism, and encapsulation to create systems that are easier to organize, scale, and maintain. OOP appears across Python, JavaScript/TypeScript, and Swift, and remains one of the most widely used paradigms in modern development.

Learn to Code for Free
Start learning now
button icon
To advance beyond this tutorial and learn to code by doing, try the interactive experience of Mimo. Whether you're starting from scratch or brushing up your coding skills, Mimo helps you take your coding journey above and beyond.

Sign up or download Mimo from the App Store or Google Play to enhance your programming skills and prepare for a career in tech.

Reach your coding goals faster