Object-Orientated Programming (OOP)
Classes create objects. Objects have properties and methods.
An object is a way of representing something in software, e.g. a person or a vehicle. Objects have instance variables, also known as properties, and methods:
- Instance variable - something about the object (property: data)
- Method - something the object can do (a sub-program: behaviour)
Declaration
The class keyword is used to declare the blueprint for new objects.
New classes are named using CapitalisedWords.
A class contains a constructor method, __init__, which is used to create a new object.
It is called automatically when an object is created.
It is normal for self to be the first parameter of any method. self refers to the current object.
Properties and methods are kept private by using a double underscore (__) before the name of a property or method.
If a property or method is private, it can only be accessed from within the object.
This is know as encapsulation.
Accessor (getter) and mutator (setter) methods will need to be provided to access or change the value of a private property.
class Person:
"""A class to define a person."""
def __init__(self, name: str='TBC', age: int=0):
"""Object constructor method. """ \
+ """Automatically called when an object is created."""
# Class properties - Private
self.__name = name
self.__age = age
def get_age(self) -> int:
"""Getter method for age."""
return self.__age
def set_age(self, age: int=0) -> None:
"""Setter method for age."""
self.__age = age
def get_name(self) -> str:
"""Getter method for name."""
return self.__name
def info(self) -> tuple:
"""Method to access person information."""
return self.__name, self.__age
An example of instantiation, creating an object, is shown below:
# Create a new object
new_person = Person('Tom', 25)
# Display their age
print(new_person.get_age())
Inheritance and Overriding
New classes can be declared that inherit the properties and methods of an existing class. The new class can be extend with additional properties and / or methods.
A method can be overridden with a new method of the same name.
class Pupil(Person):
"""A class to define a pupil. Inherits from the Person class."""
def __init__(self, name: str='TBC', age: int=5, year_group: str='P1'):
"""Object constructor method. """ \
"""Automatically called when an object is created."""
# Use superclass initilisation
super().__init__(name, age)
# Sub-class property - Private
self.__year_group = year_group
def get_year_group(self) -> str:
"""Getter method for year_group."""
return self.__year_group
def set_year_group(self, year_group: str='P1') -> None:
"""Setter method for year_group."""
self.__year_group = year_group
def info(self) -> tuple:
"""Method to access pupil information.""" \
+ """Overwrites superclass method."""
return self.get_name(), self.get_age(), self.__year_group
An example is shown below:
# Create a new object
new_pupil = Pupil('Emma', 17, 'S5')
# Display their age - Encapulation!
print(new_pupil.get_age())
Example of overiding is shown below:
# Introduce the person
details = new_person.info()
print(f'Hi, I\'m {details[0]}. I\'m {details[1]} years old.')
# Introduce the pupil
details = new_pupil.info()
print(f'Hi, I\'m {details[0]}. I\'m {details[1]} years old and in {details[2]}.')
Array of objects
The data to create an array of objects could be read from a file.
# Data for the objects
people = ['Alan,24','Beth,23','Carl,22','Dina,21']
Create an empty array.
# Empty array
array_of_objects = []
Loop for each object, create an object and append to the empty array
# Populate array
for index in range(len(people)):
# Split data at comma
data = people[index].split(',')
# Extract values
name = data[0]
age = int(data[1])
# Create new object and append to array
array_of_objects.append(Person(name, age))
Loop for each object in array.
# Loop for each object
for index in range(len(array_of_objects)):
# Get info about the current object
details = array_of_objects[index].info()
# Display info about the current object
print(f'Hi, I\'m {details[0]}. I\'m {details[1]} years old.')