100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Python

OOP Core Concepts

An introduction to the four pillars of object-oriented programming: encapsulation, abstraction, inheritance, and polymorphism.

Object-Oriented Programming FundamentalsBeginner9 min readJul 8, 2026
Analogies

Introduction

Object-oriented programming (OOP) is a programming paradigm that organizes software design around data, or objects, rather than functions and logic. An object is a bundle of state (attributes) and behavior (methods) modeled after real-world or conceptual entities. OOP became dominant because it maps naturally to how humans reason about systems: a Car has wheels and a speed, and it can accelerate or brake. Languages like Python, Java, C++, and C# all support OOP, though each implements its details slightly differently.

🏏

Cricket analogy: OOP models a cricketer the way a scout's notebook does: a player object bundles attributes like batting average and strike rate with behaviors like 'bat' or 'bowl,' letting analysts reason about Kohli or Bumrah the same natural way they'd describe them in conversation.

Explanation

OOP rests on four foundational pillars. Encapsulation bundles data and the methods that operate on it into a single unit (a class) and restricts direct access to some of an object's internal state, exposing only what is necessary through a controlled interface. Abstraction hides complex implementation details behind a simple, well-defined interface, letting users of a class interact with 'what' it does rather than 'how' it does it. Inheritance allows a new class to acquire the attributes and methods of an existing class, enabling code reuse and the modeling of 'is-a' relationships (a Dog is an Animal). Polymorphism allows objects of different classes to be treated through a common interface, with each class providing its own specific behavior for shared method names. Together these four pillars let developers build systems that are modular, reusable, and easier to reason about as they grow.

🏏

Cricket analogy: A franchise practices encapsulation by keeping a bowler's exact training regimen private inside the team's coaching staff while only revealing match-day fitness status publicly; abstraction lets fans watch Bumrah bowl a yorker without knowing his exact wrist mechanics; inheritance lets a 'PaceBowler' class extend a base 'Player' class reusing its fielding logic; polymorphism lets both a spinner and a pacer respond to the same 'bowl()' call with completely different deliveries.

Example

python
from abc import ABC, abstractmethod


class Shape(ABC):
    """Abstraction: defines a common interface for all shapes."""

    def __init__(self, name):
        self._name = name  # Encapsulation: internal state

    @abstractmethod
    def area(self):
        """Every concrete shape must implement this."""
        raise NotImplementedError


class Circle(Shape):  # Inheritance: Circle is-a Shape
    def __init__(self, radius):
        super().__init__("Circle")
        self.radius = radius

    def area(self):
        return 3.14159 * self.radius ** 2


class Rectangle(Shape):  # Inheritance: Rectangle is-a Shape
    def __init__(self, width, height):
        super().__init__("Rectangle")
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height


# Polymorphism: same method call, different behavior per class
shapes = [Circle(3), Rectangle(4, 5)]
for shape in shapes:
    print(f"{shape._name} area: {shape.area():.2f}")

Analysis

In the example, Shape demonstrates abstraction by defining an area() contract without specifying how each shape computes it. _name demonstrates encapsulation, a convention signaling internal state that callers should not modify directly. Circle and Rectangle demonstrate inheritance by extending Shape and reusing its constructor logic via super().__init__(). The loop that calls shape.area() on each object demonstrates polymorphism: the same method call produces different, type-appropriate results without the caller needing to know which concrete class it is dealing with. Each pillar has a dedicated deep-dive topic elsewhere in this module; this lesson is meant only to show how they fit together.

🏏

Cricket analogy: A franchise's generic 'Player' contract defines that everyone must have a 'perform()' method (abstraction) without saying how; a bowler's average being kept internal and only exposed through official stats is encapsulation; a 'PaceBowler' extending 'Player' and reusing its fielding setup via a base constructor is inheritance; and calling 'perform()' on both a batter and a bowler in the same loop, each producing different results, is polymorphism.

Key Takeaways

  • Encapsulation bundles data and behavior together and restricts direct access to internal state.
  • Abstraction exposes a simple interface while hiding implementation complexity.
  • Inheritance lets a class reuse and extend another class's attributes and methods.
  • Polymorphism lets different classes respond to the same method call in their own way.

Practice what you learned

Was this page helpful?

Topics covered

#Python#SoftwareEngineeringStudyNotes#SoftwareEngineering#OOPCoreConcepts#OOP#Core#Concepts#Explanation#StudyNotes#SkillVeris