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.