class Robot:
def __init__(self, name: str, batt_level=100):
self.name = name
self.batt_level = batt_level
def charge(self):
self.batt_level = 100
print(f"{self.name} is fully charged!")Inheritance 1
Introduction to Software Engineering (CSSE 1001)
Introduction
- Inheritance represents the is-a relationship, and is another way of reusing code in classes
- By inheriting from a class, we can create specialized (sub)classes while reusing attributes/methods from the original class
- Key idea: building a hierarchy of classes
- DeliveryRobot, CleanerRobot, and HuamanoidRobot all specialize the base class (i.e., Robot)
- They inherit the attributes and methods of the base class
- They can override the attributes/methods of the base class
- For example, move() method might have different implementations
- They can have new (unique) attributes/methods or implementations
Multilevel Inheritance
Some Terminology
Let’s use Figure Figure 2 as an example to explore some terminology. We can say that:
- The Student class inherits from the Person class
- The Student class is a subclass of the Person class
- The Student class is a child class of the Person class
- The Person class is a superclass of the Student class
- The Person class is a parent class of the Student class
- (less often) The Student class extends the Person class
All of these mean the same thing and can be used interchangeably.
Inheritance: Syntax
The syntax for making Child class inherit from Parent class is as follows:
class Parent():
# Parent class's implementation
# Inherit from the Parent class by adding Parent inside
# the brackets here
class Child(Parent):
# Child class's implementationInheritance: Example
Suppose we have a class Robot defined as:
And we want to create a special kind of robot, called a CleaningRobot that also has a clean() method. We could copy and paste all the code from Robot and add our own (bad!):
class CleaningRobot:
def __init__(self, name: str, batt_level=100):
self.name = name
self.batt_level = batt_level
def charge(self):
self.batt_level = 100
print(f"{self.name} is fully charged!")
def clean(self):
print(f"{self.name} is cleaning the floor.")or we could use inheritance to help us reduce duplication in our code (good!):
class CleaningRobot(Robot):
def clean(self):
print(f"{self.name} is cleaning the floor.")In this version, CleaningRobot inherits the __init__ and __charge__ methods from Robot, and only needs to include any additional behaviour (clean() method), or changes to the inherited behaviour (nothing here).
Introducing new methods
Notice that we have introduced a new method to the CleaningRobot class in the previous example. This means that the clean() method only exists (can only be called) on CleaningRobot objects.
Overriding Methods
We can override methods by declaring them (as we normally would).
class FastChargingRobot(Robot):
def charge(self): # overriding method from base class
self.batt_level = 100
print(f"{self.name} is fully charged in record time!")Calling charge() on a FastChargingRobot object will call the charge() method defined inside the FastChargingRobot class! This is as opposed to the CleaningRobot in which we inherited the charge() method from the base class, meaning that calling the charge() method on a CleaningRobot object will call the method from the Robot class.
Extending Methods
Sometimes we want the method for a subclass to perform all of the behaviour of that method in the superclass, as well as some additional behaviour. To help us reduce duplication when doing this, we can use super(), which specifies to use a method from the superclass, rather than the child class.
For example:
class DeliveryRobot(Robot):
def __init__(self, name: str, batt_level: int, load_capacity: int):
super().__init__(name, batt_level) # Calls the __init__ method from Robot
self.load_capacity = load_capacity
def deliver(self):
print(f"{self.name} is delivering a package up to {self.load_capacity}kg.")Polymorphism
The word polymorphism means to take on many forms.
In computer science, an interface that works over different underlying data-types is called polymorphic.
The length function is polymorphic:
len({'a': 1, 'b': 2, 'c': 3})3
len("Drop Bear")9
len([1, 2, 3, 4])4
Our Robot subclasses are also polymorphic!
# Polymorphism
robots = [
CleaningRobot("Roomba", 40),
DeliveryRobot("DHL-Bot", 20, 15),
FastChargingRobot("FlashBot", 5)
]
for r in robots:
r.charge() # behavior depends on class of objectRoomba is fully charged!
DHL-Bot is fully charged!
FlashBot is fully charged in record time!
Summary
We can create classes that inherit from other classes. By doing so, the subclass automatically receives all attributes and methods implemented in the superclass. The subclass can have additional methods and attributes, while overriding inherited methods and calling methods from its superclass.
Use inheritance only when there’s a clear “is-a” relationship.