Command Palette

Search for a command to run...

Object-Oriented Programming

Learn Classes, Objects, Inheritance, Encapsulation, Polymorphism, and Abstraction with real-world examples.

Why OOP?

  • OOP (Object-Oriented Programming) organizes code like real-world entities.
  • Instead of writing everything in functions, we group data and behavior together.
  • It makes code reusable, modular, and easier to understand.
  • Real-world: Car (class), my red Toyota (object).

Your First Class

  • Use the 'class' keyword to define a blueprint.
  • `__init__` is a constructor that runs when objects are created.
  • Attributes are variables inside objects, methods are functions inside classes.
  • Objects are instances of a class.
# Creating a class
class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def bark(self):
        return f"{self.name} says Woof!"
    
    def birthday(self):
        self.age += 1
        return f"{self.name} is now {self.age} years old!"

# Creating objects
dog1 = Dog("Buddy", 3)
dog2 = Dog("Max", 5)

print(dog1.bark())        # Buddy says Woof!
print(dog2.birthday())    # Max is now 6 years old!

Encapsulation - Keeping Data Safe

  • Encapsulation = binding data and methods together.
  • Single underscore `_var` means 'internal use' (convention).
  • Double underscore `__var` makes attributes private (name-mangled).
  • Access private data only via getter/setter methods.
class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.__balance = balance   # Private
    
    def deposit(self, amount):
        self.__balance += amount
        return f"Added ${amount}. New balance: ${self.__balance}"
    
    def get_balance(self):
        return self.__balance

# Usage
acc = BankAccount("Alice", 100)
print(acc.deposit(50))         # Added $50. New balance: $150
print(acc.get_balance())       # 150
# print(acc.__balance)  # Error: private attribute

Inheritance - Reusing Code

  • Inheritance allows creating new classes from existing ones.
  • Child classes inherit methods/attributes from parent classes.
  • Use super() to call parent class methods.
  • Child can override methods to change behavior.
# Parent class
class Animal:
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        return f"{self.name} makes a sound"

# Child classes
class Dog(Animal):
    def speak(self):
        return f"{self.name} barks!"

class Cat(Animal):
    def speak(self):
        return f"{self.name} meows!"

# Usage
dog = Dog("Buddy")
cat = Cat("Whiskers")
print(dog.speak())
print(cat.speak())

Polymorphism - Same Action, Different Forms

  • Polymorphism = one interface, many implementations.
  • Same method name, but behavior differs across classes.
  • Enables treating different objects uniformly.
animals = [Dog("Buddy"), Cat("Whiskers")]

for animal in animals:
    print(animal.speak())
# Buddy barks!
# Whiskers meows!

Abstraction - Hiding Details

  • Abstraction hides complex details, exposing only essentials.
  • Use Abstract Base Class (ABC) from abc module.
  • Abstract methods must be implemented by child classes.
  • You cannot instantiate abstract classes directly.
from abc import ABC, abstractmethod

class Vehicle(ABC):
    @abstractmethod
    def start_engine(self):
        pass

class Car(Vehicle):
    def start_engine(self):
        return "Car engine started with key"

class Bike(Vehicle):
    def start_engine(self):
        return "Bike engine started with button"

# Usage
car = Car()
print(car.start_engine())

Complete Example: School System

  • Person is base class with shared attributes.
  • Student and Teacher inherit from Person.
  • Encapsulation: store subjects privately.
  • Polymorphism: same introduce() works differently.
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def introduce(self):
        return f"Hi, I'm {self.name}, {self.age} years old"

class Student(Person):
    def __init__(self, name, age, grade):
        super().__init__(name, age)
        self.__subjects = []
        self.grade = grade
    
    def add_subject(self, subject):
        self.__subjects.append(subject)
        return f"{self.name} is studying {subject}"
    
    def introduce(self):
        return f"I'm {self.name}, in grade {self.grade}"

class Teacher(Person):
    def __init__(self, name, age, subject):
        super().__init__(name, age)
        self.subject = subject
    
    def teach(self, student):
        return f"{self.name} teaches {self.subject} to {student.name}"

# Usage
student = Student("Alex", 16, 10)
teacher = Teacher("Ms. Smith", 30, "Math")
print(student.introduce())
print(student.add_subject("Math"))
print(teacher.teach(student))

Key OOP Terms

  • Class → Blueprint/template for creating objects.
  • Object → Instance of a class.
  • Attribute → Data stored in an object.
  • Method → Function inside a class.
  • __init__ → Constructor, runs at object creation.
  • Encapsulation → Binding data & hiding details.
  • Inheritance → Reuse behavior across classes.
  • Polymorphism → One interface, many forms.
  • Abstraction → Hide complexity, expose essentials.

Practice Exercises

  • Create a Book class with title, author, and pages. Add a method to display info.
  • Make a Calculator class with add, subtract, multiply, divide methods.
  • Build a Student class that stores grades and calculates average.
  • Create a Rectangle class with length & width, plus area and perimeter methods.