oop February 1, 2026 β€’ 2 min read

Classes and Objects

Understanding object-oriented programming in Python with classes, objects, inheritance, and encapsulation.

Classes and Objects in Python

Object-Oriented Programming (OOP) is a programming paradigm that organizes code into objects β€” instances of classes that encapsulate data and behavior.

Defining a Class

class Dog:
    """A simple Dog class."""
    
    # Class attribute (shared by all instances)
    species = "Canis familiaris"
    
    def __init__(self, name: str, age: int):
        """Initialize a new Dog instance."""
        self.name = name    # Instance attribute
        self.age = age      # Instance attribute
    
    def bark(self) -> str:
        """Make the dog bark."""
        return f"{self.name} says Woof!"
    
    def __str__(self) -> str:
        """String representation."""
        return f"{self.name} ({self.age} years old)"

Creating Objects

# Create instances
buddy = Dog("Buddy", 5)
charlie = Dog("Charlie", 3)

print(buddy.bark())     # "Buddy says Woof!"
print(charlie.species)  # "Canis familiaris"

Inheritance

class GoldenRetriever(Dog):
    """A Golden Retriever is a type of Dog."""
    
    def __init__(self, name: str, age: int, trained: bool = False):
        super().__init__(name, age)
        self.trained = trained
    
    def fetch(self) -> str:
        return f"{self.name} fetches the ball!"

Encapsulation

Use naming conventions to indicate access levels:

class BankAccount:
    def __init__(self, balance: float):
        self._balance = balance      # Protected (convention)
        self.__pin = "1234"          # Private (name mangling)
    
    @property
    def balance(self) -> float:
        """Read-only balance property."""
        return self._balance
    
    def deposit(self, amount: float) -> None:
        if amount > 0:
            self._balance += amount

Magic Methods

Python classes support special β€œdunder” methods:

class Vector:
    def __init__(self, x: float, y: float):
        self.x = x
        self.y = y
    
    def __add__(self, other: 'Vector') -> 'Vector':
        return Vector(self.x + other.x, self.y + other.y)
    
    def __repr__(self) -> str:
        return f"Vector({self.x}, {self.y})"
    
    def __len__(self) -> float:
        return int((self.x**2 + self.y**2)**0.5)

Key Takeaway: Python’s OOP is flexible β€” you can use classes for complex structures while keeping things simple with dataclasses for pure data containers.

Related Articles