Learning Objectives
By the end of this lesson, you will be able to:
- Understand OOP terminology including objects, properties, methods, classes, inheritance, polymorphism, encapsulation, getters, setters, and instances
- Design appropriate classes to solve programming problems
- Write code demonstrating the use of OOP concepts in both pseudocode and Python
- Create classes with attributes and methods to represent real-world entities
- Implement private attributes with getter and setter methods for encapsulation
- Use constructors to initialize objects
- Apply inheritance to create subclasses that inherit from parent classes
- Implement polymorphism through method overriding
- Combine text file processing with array and class objects
- Understand containment aggregation relationships between classes
Key Terms
Class
A blueprint or template for creating objects
Object
An instance of a class with its own data and behavior
Property/Attribute
Data/variables that belong to a class or object
Method
Functions that belong to a class or object
Inheritance
A class inheriting properties and methods from another class
Polymorphism
Same method name behaving differently based on object type
Encapsulation
Bundling data with methods that operate on that data
Constructor
Special method called when an object is created
Getter/Setter
Methods to access and modify private attributes
Instance
A specific object created from a class
Containment/Aggregation
One class containing objects of another class
Access Modifiers
Keywords defining visibility of attributes/methods (public/private)
Introduction to OOP Basics
Object-Oriented Programming (OOP) is a way of writing programs by organizing the code into "objects." These objects represent things in the real world and combine attributes (data) and methods (actions). OOP makes programs easy to understand, reusable, and maintainable.
Real-Life Example: A Car
Think of a car as an object in OOP:
- Class: Car (the blueprint)
- Objects: Your specific car, your friend's car
- Attributes: color = "Red", speed = 100 km/h
- Methods: drive(), stop(), park()
Just like many cars can be made from the same blueprint, many objects can be created from the same class!
OOP Components
Class
Blueprint for creating objects (e.g., Car class)
Object
Instance of a class (e.g., myCar object)
Attributes
Data/characteristics of an object (e.g., color, speed)
Methods
Actions/functions of an object (e.g., drive(), stop())
Class Visualization: Car Class
How it works: The Car class is a blueprint. From this blueprint, we can create multiple objects (instances) like myCar, friendCar, etc. Each object has its own values for the attributes.
Writing a Simple Class
Access Modifiers: Public vs Private
Public
- Can be accessed from anywhere
- In Python: No special prefix
- In Pseudocode: PUBLIC keyword
- Example: Public methods that other code can call
Private
- Only accessible inside the class
- In Python: __ (double underscore prefix)
- In Pseudocode: PRIVATE keyword
- Example: Private attributes that need getters/setters
Activity 1: Create a Book Class
Create a class called Book with:
- Attributes:
title,author - Method:
describe()that prints: "The book [title] is written by [author]" - Create two objects of the class and call the method for both
Write your solution in both Python and Pseudocode.
Solution:
Python:
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
def describe(self):
print(f"The book '{self.title}' is written by {self.author}.")
# Create objects
book1 = Book("1984", "George Orwell")
book2 = Book("To Kill a Mockingbird", "Harper Lee")
# Call method
book1.describe()
book2.describe()
Pseudocode:
CLASS Book
PRIVATE Title : STRING
PRIVATE Author : STRING
PUBLIC PROCEDURE NEW(bookTitle : STRING, bookAuthor : STRING)
Title ← bookTitle
Author ← bookAuthor
END PROCEDURE
PUBLIC PROCEDURE Describe()
OUTPUT "The book " & Title & " is written by " & Author
END PROCEDURE
END CLASS
// Main Program
DECLARE book1, book2 : Book
book1 ← NEW Book("1984", "George Orwell")
book2 ← NEW Book("To Kill a Mockingbird", "Harper Lee")
book1.Describe()
book2.Describe()
Activity 2: Bank Account Management
Create a class named BankAccount with:
- Attributes:
AccountHolder(STRING),Balance(REAL),AccountNumber(STRING) - Method:
Deposit()that increases the Balance by a specified amount - Test this with a bank account object by depositing $500
Solution:
Python:
class BankAccount:
def __init__(self, account_holder, balance, account_number):
self.AccountHolder = account_holder
self.Balance = balance
self.AccountNumber = account_number
def Deposit(self, amount):
self.Balance += amount
print(f"${amount} deposited. New balance is ${self.Balance}.")
# Create object and test
account = BankAccount("John Doe", 1000.00, "123456789")
account.Deposit(500) # Deposit $500
Pseudocode:
CLASS BankAccount
PRIVATE AccountHolder : STRING
PRIVATE Balance : REAL
PRIVATE AccountNumber : STRING
PUBLIC PROCEDURE NEW(holder : STRING, initialBalance : REAL, accNumber : STRING)
AccountHolder ← holder
Balance ← initialBalance
AccountNumber ← accNumber
END PROCEDURE
PUBLIC PROCEDURE Deposit(amount : REAL)
Balance ← Balance + amount
OUTPUT "$" & amount & " deposited. New balance is $" & Balance
END PROCEDURE
END CLASS
// Main Program
DECLARE account : BankAccount
account ← NEW BankAccount("John Doe", 1000.00, "123456789")
account.Deposit(500) // Deposit $500
Check Your Understanding: OOP Basics
1. What is a class in OOP? [2 marks]
Answer
- [1 mark] A class is like a blueprint or template for creating objects
- [1 mark] It describes the properties (data) and methods (functions) that objects created from it will have
- [Additional] For example, a Player class defines what properties (name, score) and methods (setScore, getScore) all Player objects will have
2. What is the difference between a class and an object? [2 marks]
Answer
- [1 mark] A class is the blueprint or template (e.g., Car class)
- [1 mark] An object is an instance created from that class (e.g., myCar, yourCar)
- [Additional] You can create many objects from a single class, just like you can build many houses from the same architectural blueprint
3. What are getter and setter methods? [2 marks]
Answer
- [1 mark] A getter method retrieves/returns the value of a private property
- [1 mark] A setter method changes/sets the value of a private property
- [Additional] They provide controlled access to private attributes, allowing validation or processing when getting/setting values
4. What is the difference between public and private access modifiers? [3 marks]
Answer
- [1 mark] Public: Can be accessed from anywhere in the program
- [1 mark] Private: Only accessible inside the class where they are declared
- [1 mark] In Python, private attributes use __ (double underscore) prefix; in pseudocode, use PRIVATE keyword
5. Why do we need private attributes with getters and setters? [2 marks]
Answer
- [1 mark] Encapsulation: Protects data from being modified directly from outside the class
- [1 mark] Allows validation/processing when getting or setting values (e.g., checking if age is positive)
- [Additional] Makes code more maintainable - if we need to change how a value is stored, we only change the getter/setter methods
6. Write a simple Car class in pseudocode with brand and model attributes. [3 marks]
Answer
CLASS Car
PRIVATE Brand : STRING
PRIVATE Model : STRING
PUBLIC PROCEDURE SetDetails(carBrand : STRING, carModel : STRING)
Brand ← carBrand
Model ← carModel
END PROCEDURE
PUBLIC FUNCTION GetDetails() RETURNS STRING
RETURN Brand & " " & Model
END FUNCTION
END CLASS
// Main Program
DECLARE car1 : Car
car1 ← NEW Car()
car1.SetDetails("Toyota", "Corolla")
OUTPUT car1.GetDetails() // Outputs: Toyota Corolla
Constructors and Inheritance
Constructors are special methods that initialize objects when they are created. Inheritance allows classes to inherit properties and methods from other classes, promoting code reuse and creating hierarchical relationships.
Constructors
What is a Constructor?
A constructor is a special method automatically called when an object is created. It initializes the object's properties.
- Pseudocode: Always named
NEW - Python: Special method named
__init__ - Ensures object properties are set up when created
- Can accept parameters to initialize with specific values
Constructor Example
Python:
class Player:
def __init__(self, name, score):
self.__name = name
self.__score = score
player1 = Player("Alice", 100)
Pseudocode:
CLASS Player
PUBLIC PROCEDURE NEW(name, score)
// Initialize properties
END PROCEDURE
END CLASS
DECLARE player1 : Player
player1 ← NEW Player("Alice", 100)
Inheritance
Why Use Inheritance?
- Code Reuse: Write once in parent class, use in child classes
- Organized Code: Group similar things together
- Flexibility: Add new features to child classes without affecting parent
- Real Example: Animal → Dog, Cat, Bird (all share basic animal properties)
Inheritance Syntax
Python:
class Dog(Animal):
# Dog inherits from Animal
def bark(self):
print("Woof!")
Pseudocode:
CLASS Dog INHERITS Animal
// Dog inherits from Animal
PUBLIC PROCEDURE Bark()
OUTPUT "Woof!"
END PROCEDURE
END CLASS
Using SUPER to Call Parent Constructor
When a child class needs to initialize properties from the parent class, use SUPER to call the parent constructor:
Activity 3: Animal Shelter System
Create an animal shelter system with inheritance:
- Parent Class: Animal with properties: name, age and methods: eat(), sleep()
- Child Class: Dog that inherits from Animal with additional property: breed and additional method: bark()
- Create objects for both classes and call their methods
Solution:
Python:
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self):
print(f"{self.name} is eating.")
def sleep(self):
print(f"{self.name} is sleeping.")
class Dog(Animal):
def __init__(self, name, age, breed):
super().__init__(name, age)
self.breed = breed
def bark(self):
print(f"{self.name}, the {self.breed}, is barking!")
# Create objects
cat = Animal("Whiskers", 3)
dog = Dog("Buddy", 5, "Golden Retriever")
cat.eat()
cat.sleep()
dog.eat() # Inherited from Animal
dog.bark() # Specific to Dog
Pseudocode:
CLASS Animal
PRIVATE Name : STRING
PRIVATE Age : INTEGER
PUBLIC PROCEDURE NEW(animalName : STRING, animalAge : INTEGER)
Name ← animalName
Age ← animalAge
END PROCEDURE
PUBLIC PROCEDURE Eat()
OUTPUT Name & " is eating."
END PROCEDURE
PUBLIC PROCEDURE Sleep()
OUTPUT Name & " is sleeping."
END PROCEDURE
END CLASS
CLASS Dog INHERITS Animal
PRIVATE Breed : STRING
PUBLIC PROCEDURE NEW(dogName : STRING, dogAge : INTEGER, dogBreed : STRING)
SUPER.NEW(dogName, dogAge) // Call parent constructor
Breed ← dogBreed
END PROCEDURE
PUBLIC PROCEDURE Bark()
OUTPUT Name & ", the " & Breed & ", is barking!"
END PROCEDURE
END CLASS
// Main Program
DECLARE cat : Animal
DECLARE dog : Dog
cat ← NEW Animal("Whiskers", 3)
dog ← NEW Dog("Buddy", 5, "Golden Retriever")
cat.Eat()
cat.Sleep()
dog.Eat() // Inherited from Animal
dog.Bark() // Specific to Dog
Check Your Understanding: Constructors & Inheritance
1. What is a constructor and when is it called? [2 marks]
Answer
- [1 mark] A constructor is a special method that initializes an object's properties
- [1 mark] It is automatically called when an object is created (instantiated)
- [Additional] In pseudocode it's named NEW, in Python it's __init__
2. What is inheritance in OOP? [3 marks]
Answer
- [1 mark] Inheritance allows one class (child/subclass) to inherit properties and methods from another class (parent/superclass)
- [1 mark] Promotes code reuse - write once in parent, use in multiple children
- [1 mark] Creates hierarchical relationships (e.g., Animal → Dog, Cat, Bird)
3. Why would you use the SUPER keyword? [2 marks]
Answer
- [1 mark] To call the parent class's constructor from the child class
- [1 mark] To ensure parent class properties are properly initialized before adding child-specific properties
- [Additional] Also used to call parent class methods that have been overridden in the child class
4. Create a Vehicle class with constructor, and a Car class that inherits from it. [4 marks]
Answer
// Pseudocode solution
CLASS Vehicle
PRIVATE Brand : STRING
PRIVATE Year : INTEGER
PUBLIC PROCEDURE NEW(vehicleBrand : STRING, vehicleYear : INTEGER)
Brand ← vehicleBrand
Year ← vehicleYear
END PROCEDURE
PUBLIC FUNCTION GetDetails() RETURNS STRING
RETURN Brand & " (" & Year & ")"
END FUNCTION
END CLASS
CLASS Car INHERITS Vehicle
PRIVATE Seats : INTEGER
PUBLIC PROCEDURE NEW(carBrand : STRING, carYear : INTEGER, carSeats : INTEGER)
SUPER.NEW(carBrand, carYear) // Call parent constructor
Seats ← carSeats
END PROCEDURE
PUBLIC FUNCTION GetDetails() RETURNS STRING
RETURN SUPER.GetDetails() & " with " & Seats & " seats"
END FUNCTION
END CLASS
// Python solution would be similar with:
// class Car(Vehicle):
// def __init__(self, brand, year, seats):
// super().__init__(brand, year)
// self.__seats = seats
Polymorphism and Advanced Concepts
Polymorphism means "many forms." It allows the same method name to behave differently based on the object that calls it. With polymorphism, you can call the same method on objects of different classes, and each class can provide its own implementation.
Real-Life Example: Animal Sounds
Different animals make different sounds, but they all have a "speak" method:
- Dog.speak() → "Woof Woof"
- Cat.speak() → "Meow"
- Bird.speak() → "Chirp Chirp"
- Cow.speak() → "Moo"
Same method name (speak()), different implementations for each animal class!
Key Points of Polymorphism
Method Overriding
Subclass provides specific implementation of method from parent class
Shared Interface
Treat objects of different classes as objects of common parent class
Flexibility
Code works with objects of multiple types in unified way
Polymorphism Simulation: Animal Sounds
How it works: Even though all objects are stored in an Animal array, when animal.speak() is called, Python checks the actual object type at runtime and calls the appropriate method. This is polymorphism in action!
Activity 4: Vehicle System with Polymorphism
Create a Vehicle system demonstrating polymorphism:
- Create a
Vehicleparent class with methodget_details() - Create
CarandTrucksubclasses that overrideget_details() - Create a list of vehicles containing both Car and Truck objects
- Loop through the list and call
get_details()on each
Solution:
Python:
class Vehicle:
def get_details(self):
return "Generic vehicle"
class Car(Vehicle):
def get_details(self): # Override
return "Car: Passenger vehicle with 4-5 seats"
class Truck(Vehicle):
def get_details(self): # Override
return "Truck: Heavy goods vehicle"
# Create list of vehicles
vehicles = [Car(), Truck(), Car()]
# Polymorphism in action
for vehicle in vehicles:
print(vehicle.get_details())
# Output:
# Car: Passenger vehicle with 4-5 seats
# Truck: Heavy goods vehicle
# Car: Passenger vehicle with 4-5 seats
Pseudocode:
CLASS Vehicle
PUBLIC FUNCTION GetDetails() RETURNS STRING
RETURN "Generic vehicle"
END FUNCTION
END CLASS
CLASS Car INHERITS Vehicle
PUBLIC FUNCTION GetDetails() RETURNS STRING
RETURN "Car: Passenger vehicle with 4-5 seats"
END FUNCTION
END CLASS
CLASS Truck INHERITS Vehicle
PUBLIC FUNCTION GetDetails() RETURNS STRING
RETURN "Truck: Heavy goods vehicle"
END FUNCTION
END CLASS
// Main Program
DECLARE vehicles : ARRAY OF Vehicle
DECLARE i : INTEGER
vehicles ← [NEW Car(), NEW Truck(), NEW Car()]
FOR i ← 0 TO LENGTH(vehicles) - 1
OUTPUT vehicles[i].GetDetails()
NEXT i
// Output:
// Car: Passenger vehicle with 4-5 seats
// Truck: Heavy goods vehicle
// Car: Passenger vehicle with 4-5 seats
Check Your Understanding: Polymorphism
1. What does polymorphism mean in OOP? [2 marks]
Answer
- [1 mark] Polymorphism means "many forms"
- [1 mark] It allows the same method name to behave differently based on the object that calls it
- [Additional] Different classes can provide their own implementation of the same method
2. What is method overriding? [2 marks]
Answer
- [1 mark] A subclass provides its own specific implementation of a method already defined in the parent class
- [1 mark] The child class method "overrides" the parent class method
- [Additional] Example: Dog.speak() overrides Animal.speak() with "Woof" instead of generic sound
3. How is polymorphism useful in arrays/loops? [3 marks]
Answer
- [1 mark] You can store objects of different subclasses in an array of the parent class type
- [1 mark] When looping through the array and calling a method, each object uses its own implementation
- [1 mark] This allows writing generic code that works with multiple object types
- [Additional] Example: Animal array with Dog, Cat objects - all can call speak() but produce different sounds
Key Takeaways
- OOP organizes code into objects with attributes (data) and methods (actions)
- A class is a blueprint for creating objects; objects are instances of classes
- Encapsulation bundles data with methods and uses private attributes with getters/setters for controlled access
- Constructors (__init__ in Python, NEW in pseudocode) initialize objects when created
- Inheritance allows code reuse - child classes inherit from parent classes
- Use SUPER to call parent constructors and methods from child classes
- Polymorphism means "many forms" - same method name behaves differently based on object type
- Method overriding allows subclasses to provide specific implementations of parent methods
- Public attributes/methods are accessible from anywhere; private ones only within the class
- OOP makes code more modular, reusable, and maintainable for complex programs
- Real-world systems like banking, e-commerce, and games use OOP principles extensively
Question Bank
1. Explain the main principles of Object-Oriented Programming. [6 marks]
Marking Scheme & Answer
- [2 marks] Encapsulation: Bundling data (attributes) with methods that operate on that data. Using private attributes with getters/setters for controlled access.
- [2 marks] Inheritance: Creating new classes (child classes) that inherit properties and methods from existing classes (parent classes). Promotes code reuse.
- [2 marks] Polymorphism: Same method name behaving differently based on object type. Method overriding in subclasses provides specific implementations.
- [Additional] Classes and Objects: Classes are blueprints, objects are instances. Abstraction: Hiding complex implementation details.
2. Compare and contrast classes and objects. [4 marks]
Marking Scheme & Answer
Class:
- Blueprint or template
- Defines attributes and methods
- Exists only once in memory
- Example: Car class
Object:
- Instance of a class
- Has actual values for attributes
- Multiple objects can exist
- Example: myCar, yourCar objects
3. What are constructors and why are they important? [4 marks]
Marking Scheme & Answer
- [1 mark] Constructors are special methods called when an object is created
- [1 mark] They initialize the object's properties/attributes
- [1 mark] In Python:
__init__method; in Pseudocode:NEWprocedure - [1 mark] Important because they ensure objects start with valid/initialized state
- [Additional] Can accept parameters to initialize with specific values, can call parent constructors using super()
4. Explain inheritance with a real-world example. [5 marks]
Marking Scheme & Answer
- [1 mark] Inheritance allows a class (child) to inherit properties and methods from another class (parent)
- [2 marks] Real-world example: Vehicle → Car, Truck, Motorcycle
- Vehicle class has common properties: brand, model, year
- Car inherits from Vehicle and adds: numberOfDoors
- Truck inherits from Vehicle and adds: cargoCapacity
- [1 mark] Promotes code reuse - common code in Vehicle, specific code in subclasses
- [1 mark] Creates hierarchical relationships making code organized and maintainable
5. What is polymorphism and how is it implemented? [5 marks]
Marking Scheme & Answer
- [1 mark] Polymorphism means "many forms" - same method name behaving differently based on object
- [2 marks] Implementation through method overriding:
- Parent class defines method
- Child classes override with specific implementations
- Example: Animal.speak() vs Dog.speak() vs Cat.speak()
- [1 mark] Allows treating objects of different classes as objects of common parent class
- [1 mark] Useful in arrays/loops - store different objects together, call same method on each
6. Why are getter and setter methods important for encapsulation? [4 marks]
Marking Scheme & Answer
- [1 mark] Getter methods retrieve values of private attributes; setter methods modify them
- [1 mark] Provide controlled access to private data - can't be accessed/modified directly
- [1 mark] Allow validation in setters (e.g., check if age is positive before setting)
- [1 mark] Enable encapsulation - data bundled with methods, implementation details hidden
- [Additional] Makes code more maintainable - if storage changes, only getter/setter needs updating