Day 13: Introduction to Object-Oriented Programming — Classes & Objects
🐍 Day 13: Introduction to Object-Oriented Programming — Classes & Objects
1. Learning Objectives
By the end of Day 13, you will be able to:
- Understand what Object-Oriented Programming (OOP) is and why it matters
- Define your own classes to create custom data types
- Use the
__init__method to initialize object attributes - Differentiate between instance attributes and class attributes
- Create objects (instances) from a class and call their methods
- Read and write code that models real-world entities as classes
- Recognize the
selfparameter and how it works
2. Concept Explanation
2.1 Why Object-Oriented Programming? — From Functions to Blueprints
So far, you've organised code into functions and modules — great for reuse. But as programs grow, managing related data and behaviour with plain dictionaries and lists becomes messy.
OOP bundles data (attributes) and behaviour (methods) into a single structure called an object. Think of a class as a blueprint and an object as the thing you build from that blueprint.
| Real-World Analogy | Python OOP |
|---|---|
| Blueprint of a house | class |
| Actual houses built from it | Objects (instances) |
| Features: colour, number of rooms | Attributes (data) |
| Actions: open door, turn on lights | Methods (functions inside class) |
Using OOP, you can model a BankAccount, a Student, a Car — anything with properties and behaviour — in clean, reusable code.
2.2 Defining a Class — The class Keyword
A class is defined with the class keyword, followed by a name (PascalCase) and a colon. The body contains methods (functions) and attributes.
class Dog:
"""A simple Dog class."""
# The __init__ method (constructor) runs when a new Dog is created
def __init__(self, name, age):
# self refers to the specific instance being created
self.name = name # instance attribute
self.age = age
# A method: a function that belongs to the class
def bark(self):
print(f"{self.name} says Woof!")
def birthday(self):
self.age += 1
print(f"Happy birthday {self.name}! You are now {self.age}.")
2.3 __init__ — The Constructor
__init__ is a special method called automatically when you create a new instance. It sets up the object's initial state.
- The first parameter is always
self(you can name it anything, butselfis the universal convention). selfrefers to the instance that is being created or used.
2.4 Creating Objects (Instances)
You create an object by calling the class like a function:
# Create two different Dog objects
my_dog = Dog("Rex", 3)
your_dog = Dog("Bella", 1)
# Access attributes using dot notation
print(my_dog.name) # Rex
print(your_dog.age) # 1
# Call methods
my_dog.bark() # Rex says Woof!
your_dog.birthday() # Happy birthday Bella! You are now 2.
Each object has its own copy of instance attributes. my_dog and your_dog are independent.
2.5 Instance vs. Class Attributes
- Instance attributes are defined inside
__init__withself.— each object has its own value. - Class attributes are defined directly inside the class body, shared by all instances.
class Student:
school = "Python University" # Class attribute
def __init__(self, name, grade):
self.name = name # Instance attribute
self.grade = grade
s1 = Student("Alice", 85)
s2 = Student("Bob", 92)
print(s1.school) # Python University (shared)
print(s2.school) # Python University
# Change class attribute for all
Student.school = "Code Academy"
print(s1.school) # Code Academy
print(s2.school) # Code Academy
2.6 Methods — Functions Inside a Class
Methods are functions that belong to a class and usually operate on instance data. The first parameter is always self.
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
r = Rectangle(5, 3)
print(r.area()) # 15
print(r.perimeter()) # 16
Methods can also take additional parameters after self.
2.7 The self Parameter Explained
self is not a keyword but a universally used convention. It refers to the current instance, allowing you to access its attributes and other methods.
class Counter:
def __init__(self):
self.count = 0
def increment(self):
self.count += 1 # Accesses instance attribute
def get_count(self):
return self.count
When you call obj.method(), Python automatically passes obj as the first argument (self).
2.8 Common Mistakes
| Mistake | Why It Happens |
|---|---|
Forgetting self as first parameter in method | TypeError: method() takes 0 positional arguments but 1 was given |
| Calling a method without parentheses | r.area returns the method object, doesn't run it |
| Using class name instead of instance | Dog.bark() fails; you need an instance: my_dog.bark() |
| Confusing class and instance attributes | Modifying obj.class_attr creates an instance attribute, doesn't change class attr |
3. Code Examples
Example 1: Bank Account Class
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner
self.balance = balance
def deposit(self, amount):
if amount > 0:
self.balance += amount
print(f"Deposited ${amount:.2f}. New balance: ${self.balance:.2f}")
else:
print("Amount must be positive.")
def withdraw(self, amount):
if 0 < amount <= self.balance:
self.balance -= amount
print(f"Withdrew ${amount:.2f}. New balance: ${self.balance:.2f}")
else:
print("Invalid amount or insufficient funds.")
def display(self):
print(f"Account owner: {self.owner}, Balance: ${self.balance:.2f}")
acc = BankAccount("Alice", 1000)
acc.display()
acc.deposit(250)
acc.withdraw(300)
Example 2: Student Grade Tracker
class Student:
def __init__(self, name):
self.name = name
self.grades = []
def add_grade(self, grade):
self.grades.append(grade)
def average(self):
if not self.grades:
return 0
return sum(self.grades) / len(self.grades)
def __str__(self):
return f"{self.name} - Grades: {self.grades}, Average: {self.average():.2f}"
s = Student("Bob")
s.add_grade(85)
s.add_grade(92)
print(s)
Example 3: Class Attribute Counter
class Employee:
company = "TechCorp"
total_employees = 0 # class-level counter
def __init__(self, name):
self.name = name
Employee.total_employees += 1
def __del__(self): # called when object is deleted (rarely needed)
Employee.total_employees -= 1
e1 = Employee("Alice")
e2 = Employee("Bob")
print(Employee.total_employees) # 2
4. Hands-On Exercises
Exercise 1: Basic Class Creation
Create a Book class with attributes title, author, and pages. Write a method info() that returns a string like "Title: Python 101, Author: Guido, Pages: 300". Create two book objects and print their info.
Exercise 2: Rectangle Class
Define a Rectangle class with attributes width and height. Add methods area() and perimeter(). Create an instance and print both area and perimeter.
Exercise 3: Temperature Converter Class
Create a Temperature class that stores a temperature in Celsius. Add methods to_fahrenheit() (returns celsius * 9/5 + 32) and to_kelvin() (returns celsius + 273.15). Test with 25°C.
Exercise 4: Shopping Cart
Build a ShoppingCart class. It should maintain a list of items (strings). Methods: add_item(item), remove_item(item), view_cart(), and clear_cart(). Test all operations.
Exercise 5: Class vs Instance Attribute Experiment
Create a Car class with a class attribute wheels = 4 and instance attributes make and model. Create two cars. Print Car.wheels and car1.wheels. Then change car1.wheels = 3 — what happens to car2.wheels and Car.wheels? Explain.
5. Applied Challenge Task 🏗️
Library Management System
Design a simple library system using OOP. Create three classes:
Book class:
- Attributes:
title,author,isbn,is_available(defaultTrue) - Methods:
borrow()(setis_availabletoFalse, print confirmation),return_book()(set toTrue),__str__()returns book info and availability
Member class:
- Attributes:
name,member_id,borrowed_books(list) - Methods:
borrow(book)— if book is available, borrow it and add to list. If not, print message.return_book(book)— remove from list, mark book as available.list_borrowed()— print borrowed books.
Library class:
- Attributes:
books(list of Book objects),members(list of Member objects) - Methods:
add_book(book),register_member(member),find_book_by_title(title)returning Book or None,display_available_books()
Then write a small menu-driven program to test the system: add books, register members, borrow/return books, list available books.
Example usage:
Library Menu:
1. Add Book
2. Register Member
3. Borrow Book
4. Return Book
5. Show Available Books
6. Show Member Borrowed Books
7. Exit
Stretch goals:
- Add a simple ID generation for members
- Prevent borrowing if member already has 3 books
- Save/Load library data using JSON and file I/O (from Days 9/12)
6. Brief Review Summary
| Concept | Key Points |
|---|---|
| OOP | Bundles data and behaviour into objects |
| Class | Blueprint defined with class keyword |
| Object | Instance of a class, created by calling the class |
__init__ | Constructor — initialises instance attributes |
self | Refers to the current instance (first parameter of methods) |
| Instance attributes | Unique to each object, set with self. |
| Class attributes | Shared by all instances, defined outside __init__ |
| Methods | Functions inside a class, first parameter is self |
| Dot notation | object.attribute or object.method() |
7. Preview of Next Topic — Day 14
Tomorrow we deepen OOP with the three pillars:
- Inheritance — creating child classes that reuse and extend parent behaviour
- Encapsulation — controlling access to attributes (private/public conventions)
- Polymorphism — different classes sharing the same interface
- Method overriding and
super()
🎯 Your Action Items for Day 13:
- ✅ Complete all 5 exercises
- ✅ Build the Library Management System
- ✅ Experiment with class vs instance attributes — break it intentionally
- ✅ Write a class that models something from your life (phone, pet, game character)
Comments
Post a Comment
Leave us your comments here...