OOP: Classes & Objects
Learn the fundamentals of Object-Oriented Programming in Python
What is Object-Oriented Programming?
Object-Oriented Programming (OOP) is a programming paradigm that uses "objects" to design applications and computer programs. It utilizes several techniques including encapsulation, polymorphism, and inheritance.
Classes and Objects
A class is a blueprint for creating objects. An object is an instance of a class.
# Defining a class
class Dog:
# Class attribute
species = "Canis familiaris"
# Initializer / Instance attributes
def __init__(self, name, age):
self.name = name
self.age = age
# Instance method
def description(self):
return f"{self.name} is {self.age} years old"
# Another instance method
def speak(self, sound):
return f"{self.name} says {sound}"
# Creating objects (instances of the Dog class)
dog1 = Dog("Buddy", 5)
dog2 = Dog("Milo", 3)
# Accessing attributes and methods
print(dog1.name) # Buddy
print(dog2.age) # 3
print(dog1.description()) # Buddy is 5 years old
print(dog2.speak("Woof")) # Milo says Woof
The __init__ Method
The __init__
method is a special method that is automatically called when a new object is created. It's used to initialize the object's attributes.
class Car:
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0 # Default value
def get_descriptive_name(self):
return f"{self.year} {self.make} {self.model}"
def read_odometer(self):
return f"This car has {self.odometer_reading} miles on it"
# Create a car object
my_car = Car("Toyota", "Camry", 2020)
print(my_car.get_descriptive_name()) # 2020 Toyota Camry
print(my_car.read_odometer()) # This car has 0 miles on it
Upgrade Your Learning Experience!
Get access to premium content, exercises, and projects with OjoTech Pro
Learn MoreModifying Attributes
You can modify an attribute's value directly or through a method:
class Car:
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
def update_odometer(self, mileage):
if mileage >= self.odometer_reading:
self.odometer_reading = mileage
else:
print("You can't roll back an odometer!")
def increment_odometer(self, miles):
self.odometer_reading += miles
my_car = Car("Toyota", "Camry", 2020)
# Modify attribute directly
my_car.odometer_reading = 23
print(my_car.odometer_reading) # 23
# Modify through a method
my_car.update_odometer(50)
print(my_car.odometer_reading) # 50
my_car.increment_odometer(100)
print(my_car.odometer_reading) # 150
Inheritance
Inheritance allows you to define a class that inherits all the methods and properties from another class.
# Parent class
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
raise NotImplementedError("Subclass must implement this method")
# Child class
class Dog(Animal):
def speak(self):
return f"{self.name} says Woof!"
# Child class
class Cat(Animal):
def speak(self):
return f"{self.name} says Meow!"
# Create objects
dog = Dog("Buddy")
cat = Cat("Whiskers")
print(dog.speak()) # Buddy says Woof!
print(cat.speak()) # Whiskers says Meow!
Practice Exercise
Create a BankAccount
class that:
- Has attributes for account number, owner name, and balance
- Has methods to deposit, withdraw, and display balance
- Prevents withdrawals if insufficient funds
- Create a
SavingsAccount
class that inherits from BankAccount and adds interest calculation
Polymorphism
Polymorphism allows methods to do different things based on the object it is acting upon.
class Bird:
def fly(self):
return "Most birds can fly"
class Penguin(Bird):
def fly(self):
return "Penguins can't fly"
class Sparrow(Bird):
def fly(self):
return "Sparrows can fly very fast"
# Function that uses polymorphism
def bird_flying_test(bird):
print(bird.fly())
# Create objects
generic_bird = Bird()
penguin = Penguin()
sparrow = Sparrow()
# Test polymorphism
bird_flying_test(generic_bird) # Most birds can fly
bird_flying_test(penguin) # Penguins can't fly
bird_flying_test(sparrow) # Sparrows can fly very fast
Take Your Python Skills to the Next Level
OjoTech Pro offers advanced courses, real-world projects, and mentorship to help you become a Python expert
Advanced Projects
Build portfolio-worthy applications with guided projects
Expert Mentorship
Get personalized feedback and guidance from industry experts
Certification
Earn a certificate to showcase your Python programming skills
Encapsulation
Encapsulation is the bundling of data with the methods that operate on that data. In Python, we use naming conventions to indicate protected and private attributes.
class BankAccount:
def __init__(self, account_number, owner_name, balance=0):
self.account_number = account_number # Public attribute
self.owner_name = owner_name # Public attribute
self._balance = balance # Protected attribute (convention)
# Public method to access protected attribute
def get_balance(self):
return self._balance
# Public method to modify protected attribute with validation
def deposit(self, amount):
if amount > 0:
self._balance += amount
return True
return False
def withdraw(self, amount):
if 0 < amount <= self._balance:
self._balance -= amount
return True
return False
account = BankAccount("123456", "John Doe", 1000)
print(account.get_balance()) # 1000
account.deposit(500)
print(account.get_balance()) # 1500
account.withdraw(200)
print(account.get_balance()) # 1300
Special Methods
Python has special methods that begin and end with double underscores. They are also known as "magic methods".
class Book:
def __init__(self, title, author, pages):
self.title = title
self.author = author
self.pages = pages
# String representation of the object
def __str__(self):
return f"'{self.title}' by {self.author}"
# Length of the object
def __len__(self):
return self.pages
# What happens when object is deleted
def __del__(self):
print(f"A book object '{self.title}' has been deleted")
# Create a book object
book = Book("Python Basics", "John Smith", 200)
print(str(book)) # 'Python Basics' by John Smith
print(len(book)) # 200
del book # A book object 'Python Basics' has been deleted
Class Methods and Static Methods
Class methods work with the class rather than instances. Static methods are utility functions that don't work with class or instance data.
class MyClass:
class_attribute = "I'm a class attribute"
def __init__(self, value):
self.instance_attribute = value
# Instance method
def instance_method(self):
return f"Instance method called with {self.instance_attribute}"
# Class method
@classmethod
def class_method(cls):
return f"Class method called with {cls.class_attribute}"
# Static method
@staticmethod
def static_method():
return "Static method called"
# Using instance method
obj = MyClass("test")
print(obj.instance_method()) # Instance method called with test
# Using class method
print(MyClass.class_method()) # Class method called with I'm a class attribute
# Using static method
print(MyClass.static_method()) # Static method called
OOP Principles Summary
Principle | Description | Python Example |
---|---|---|
Encapsulation | Bundling data and methods that work on that data within one unit | Using classes with attributes and methods |
Inheritance | Creating a new class from an existing class | class ChildClass(ParentClass): |
Polymorphism | Using a single type entity to represent different types in different scenarios | Method overriding in child classes |
Abstraction | Hiding the implementation details and showing only functionality | Using abstract base classes (ABC module) |