-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinheritance.qmd
More file actions
152 lines (105 loc) · 4.5 KB
/
inheritance.qmd
File metadata and controls
152 lines (105 loc) · 4.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
---
filters:
- pyodide
---
# Inheritance
{{< video https://youtu.be/7oJ0zvA-UMM >}}
In Object Oriented Programming, we can also have classes that are based on other classes. This is known as inheritance.
In our example, we could create a Vehicle class that has attributes and methods applicable to all vehicles, and then create an Ambulance class which inherits this stuff but adds its own ambulance-specific things too.
This improves efficiency if we need to write multiple classes that are similar.
In this example, the Vehicle class would be known as the parent and the Ambulance class as the child.

You can see how powerful this may be if we have lots of different child classes.

## Inheritance in Python
{{< video https://youtu.be/ncw0TuXUV1U >}}
Inheritance is really easy to do in Python.
We'll start by creating our parent class.
Note we don't have to do anything special here - we just define our class as normal, but only containing the things we want to be common to all child classes.
```{pyodide-python}
class Vehicle:
def __init__(self, reg_number):
self.reg_number = reg_number
def drive(self, speed):
print (f"Now driving at {speed}mph")
def park(self, location):
print (f"Now parked at {location}")
```
Let's create our first child class.
The key bits here are as follows:
```{python}
#| eval: false
class Ambulance(Vehicle):
def __init__(self, reg_number):
# This calls the constructor of the parent (super), and passes the reg
# number across to it
super().__init__(reg_number)
```
Notice when we create the `Ambulance` class, we put the `Vehicle` class inside the brackets at the beginning.
This tells the class to use the `Vehicle` class as the parent class.
We then need to run the line
```
super().__init__()
```
to call the constructor of the parent class.
In our case, we also want to pass the `reg_number` to the parent class, so our line looks like this.
```
super().__init__(reg_number)
```
The full class looks like this:
```{pyodide-python}
# We pass Vehicle into Ambulance. This defines Vehicle as the parent, and
# Ambulance as the child.
class Ambulance(Vehicle):
def __init__(self, reg_number):
# This calls the constructor of the parent (super), and passes the reg
# number across to it
super().__init__(reg_number)
self.patient_on_board = False
self.siren_on = False
# We don't need to redefine drive() and park() (unless we want to change
# them for an ambulance) as we inherit them automatically. So we just
# define any methods unique to an ambulance. (If we do want to change one
# of the inherited methods, we just redefine them here, with the same name)
def load_patient(self, patient_name):
self.patient_on_board = True
print (f"{patient_name} now on board")
def unload_patient(self, patient_name):
self.patient_on_board = False
print (f"{patient_name} unloaded")
def turn_on_siren(self):
self.siren_on = True
print ("Nee nor nee nor nee nor nee nor nee nor")
def turn_off_siren(self):
self.siren_on = False
```
You can see that other than the `__init__` method, the rest of the code (i.e. each method) is actually the same as our earlier ambulance code.
Let's create two more child classes: `bus` and `car`.
```{pyodide-python}
class Bus(Vehicle):
def __init__(self, reg_number, passenger_capacity):
super().__init__(reg_number)
self.passenger_capacity = passenger_capacity
def open_doors(self):
print ("Doors are open")
def close_doors(self):
print ("Doors are closed")
def take_fare(self, fare_amount):
print (f"Taken {fare_amount} as fare")
```
```{pyodide-python}
class Car(Vehicle):
def __init__(self, reg_number, number_of_doors):
super().__init__(reg_number)
self.number_of_doors = number_of_doors
def open_boot(self):
print ("Boot is open")
def close_boot(self):
print ("Boot is closed")
```
When we want to instantiate an ambulance, we do it exactly the same as before.
It’s just we’ve saved ourselves having to rewrite some of the definitions that are common to vehicles.
```{.callout-note}
If the child class contains no differences in its constructor from the parent class, then you don’t need to define the constructor at all in the child class.
It will automatically use the parent class constructor on instantiation.
```