1
1

00:00:00,960  -->  00:00:02,620
<v ->Hi guys, and welcome back!</v>
2

2

00:00:02,620  -->  00:00:04,350
In this video, we're going to start talking
3

3

00:00:04,350  -->  00:00:06,780
about class inheritance.
4

4

00:00:06,780  -->  00:00:10,800
Inheritance allows one class to take some methods
5

5

00:00:10,800  -->  00:00:12,950
and properties from another class.
6

6

00:00:12,950  -->  00:00:14,660
Let's have a look.
7

7

00:00:14,660  -->  00:00:17,060
Imagine you've got a class called Device,
8

8

00:00:17,060  -->  00:00:20,150
such as a USB device or something like that.
9

9

00:00:20,150  -->  00:00:23,070
And you want it to represent just anything
10

10

00:00:23,070  -->  00:00:25,560
you might plug into your computer.
11

11

00:00:25,560  -->  00:00:27,720
So I'm going to define my init method,
12

12

00:00:27,720  -->  00:00:31,420
and then we're going to be able to give these devices names
13

13

00:00:31,420  -->  00:00:34,700
and how they are connected, such as by a USB.
14

14

00:00:34,700  -->  00:00:36,763
So I'll say, connected by.
15

15

00:00:37,670  -->  00:00:40,090
Then we'll say self.name=name,
16

16

00:00:40,090  -->  00:00:43,870
self.connected by=connected by,
17

17

00:00:43,870  -->  00:00:45,740
and we're also going to assume
18

18

00:00:45,740  -->  00:00:49,270
that when you create a device object,
19

19

00:00:49,270  -->  00:00:52,240
that is going to represent a connected device,
20

20

00:00:52,240  -->  00:00:54,690
something that is already connected to your computer.
21

21

00:00:54,690  -->  00:00:57,143
So we'll say self.connecte=true.
22

22

00:00:58,150  -->  00:01:00,690
We are going to assume that it's connected
23

23

00:01:00,690  -->  00:01:03,810
and we don't have to pass in a parameter for that.
24

24

00:01:03,810  -->  00:01:05,373
We can just say true here.
25

25

00:01:06,370  -->  00:01:11,370
Then, we will type str and we're gonna say return f
26

26

00:01:12,180  -->  00:01:16,390
device self.name, and we're going to put !r
27

27

00:01:17,730  -->  00:01:19,840
and we're gonna say self.connected_by.
28

28

00:01:19,840  -->  00:01:21,360
The exclamation mark r,
29

29

00:01:21,360  -->  00:01:25,300
calls the repr method of self.name,
30

30

00:01:25,300  -->  00:01:28,260
so that it shows up as having the quotes already.
31

31

00:01:28,260  -->  00:01:29,740
So this is just a little bit nicer
32

32

00:01:29,740  -->  00:01:31,060
than putting the quotes in yourself.
33

33

00:01:31,060  -->  00:01:34,880
Then we're also going to add a disconnect method,
34

34

00:01:34,880  -->  00:01:38,290
which just says self.connected=false
35

35

00:01:38,290  -->  00:01:40,570
and the prints out disconnected.
36

36

00:01:40,570  -->  00:01:43,580
So you have this class device here.
37

37

00:01:43,580  -->  00:01:45,580
This device doesn't do much at the moment,
38

38

00:01:45,580  -->  00:01:49,020
but you could do something like printer=device
39

39

00:01:49,020  -->  00:01:52,550
and call it Printer and say it's connected via USB,
40

40

00:01:52,550  -->  00:01:54,820
and then you can print it out.
41

41

00:01:54,820  -->  00:01:57,740
Finally, you can also disconnect it.
42

42

00:01:57,740  -->  00:01:59,390
All right, let's press play.
43

43

00:01:59,390  -->  00:02:02,740
And you can see that you get Device, Printer, USB,
44

44

00:02:02,740  -->  00:02:05,370
and then disconnected, so very good.
45

45

00:02:05,370  -->  00:02:09,560
Now, let's say you want to add functionality to this class
46

46

00:02:09,560  -->  00:02:13,130
that allows it to print things out.
47

47

00:02:13,130  -->  00:02:15,120
For example, it can print a certain number of pages,
48

48

00:02:15,120  -->  00:02:16,650
or something like that.
49

49

00:02:16,650  -->  00:02:20,930
This class here is not a printer, this is a device.
50

50

00:02:20,930  -->  00:02:23,260
Could be a printer, but it could also be a webcam,
51

51

00:02:23,260  -->  00:02:25,150
or a microphone, it could be anything.
52

52

00:02:25,150  -->  00:02:26,670
So we don't want to add
53

53

00:02:26,670  -->  00:02:30,570
printer specific functionality to this class.
54

54

00:02:30,570  -->  00:02:34,190
You could rename the class and turn it into a Printer class,
55

55

00:02:34,190  -->  00:02:36,740
but you can also create another class
56

56

00:02:36,740  -->  00:02:41,420
that uses all of these methods and has more,
57

57

00:02:41,420  -->  00:02:44,350
and that is where inheritance comes in.
58

58

00:02:44,350  -->  00:02:46,940
So we're going to create a printer class now,
59

59

00:02:46,940  -->  00:02:48,150
and we're going to do something new,
60

60

00:02:48,150  -->  00:02:50,750
which is put a pair of brackets after it,
61

61

00:02:50,750  -->  00:02:53,430
and here we're going to put Device.
62

62

00:02:53,430  -->  00:02:54,480
And what this tells Python
63

63

00:02:54,480  -->  00:02:56,670
is that you're creating a new class called Printer
64

64

00:02:56,670  -->  00:02:59,820
and it inherits from Device, which means that it will
65

65

00:02:59,820  -->  00:03:03,190
essentially copy and paste all of these methods.
66

66

00:03:03,190  -->  00:03:04,680
It won't quite do that,
67

67

00:03:04,680  -->  00:03:07,990
but you will be able to use these methods from this class.
68

68

00:03:07,990  -->  00:03:10,940
So, let's start by defining an init method.
69

69

00:03:10,940  -->  00:03:14,480
Now, this printer object is going to need a name,
70

70

00:03:14,480  -->  00:03:18,640
just like a device, e-connected by just like the device,
71

71

00:03:18,640  -->  00:03:21,850
and it's also going to have a capacity.
72

72

00:03:21,850  -->  00:03:24,280
How many pages left of ink?
73

73

00:03:24,280  -->  00:03:26,380
Then, what we're going to do is,
74

74

00:03:26,380  -->  00:03:28,690
instead of doing self.name=name,
75

75

00:03:28,690  -->  00:03:33,690
self.connect by=connected by, self.connected=true.
76

76

00:03:34,030  -->  00:03:35,210
Instead of doing that,
77

77

00:03:35,210  -->  00:03:37,910
which as you can see is a copy paste of this method here,
78

78

00:03:37,910  -->  00:03:42,820
we can just call the parent class device init method.
79

79

00:03:42,820  -->  00:03:47,053
So, what to do in Python 3, is to do super.init.
80

80

00:03:49,040  -->  00:03:52,440
So, super and then a pair of brackets,
81

81

00:03:52,440  -->  00:03:53,560
and what this does in Python
82

82

00:03:53,560  -->  00:03:56,760
is it gets the super class, or the parent class,
83

83

00:03:56,760  -->  00:03:58,600
which in this case is Device,
84

84

00:03:58,600  -->  00:04:02,300
and it's going to call the init method of that super class..
85

85

00:04:02,300  -->  00:04:06,260
Of course, the init-method needs a name and a connected by,
86

86

00:04:06,260  -->  00:04:08,850
so we would pass a name and connected by.
87

87

00:04:08,850  -->  00:04:10,260
These are two parameters.
88

88

00:04:10,260  -->  00:04:11,960
We still have capacity.
89

89

00:04:11,960  -->  00:04:15,550
So, we will say self.capacity=capacity
90

90

00:04:16,500  -->  00:04:20,260
and self.remaining pages=capacity.
91

91

00:04:20,260  -->  00:04:24,310
Why am I doing two properties with the same value?
92

92

00:04:24,310  -->  00:04:28,410
The capacity is the maximum amount of pages
93

93

00:04:28,410  -->  00:04:31,820
that a printer could potentially print, if it had full ink.
94

94

00:04:31,820  -->  00:04:34,280
Whereas the remaining pages is how many are left
95

95

00:04:34,280  -->  00:04:36,100
after printing some.
96

96

00:04:36,100  -->  00:04:38,340
So, you can think of this as maximum capacity
97

97

00:04:38,340  -->  00:04:39,933
and this as current capacity.
98

98

00:04:40,900  -->  00:04:43,793
Then, we are going to define an str method,
99

99

00:04:45,040  -->  00:04:47,160
and here we're going to return
100

100

00:04:48,070  -->  00:04:51,240
the super classes str method.
101

101

00:04:51,240  -->  00:04:56,240
And then we're also going to put in self.remaining pages,
102

102

00:04:56,560  -->  00:04:58,690
pages remaining, something like that.
103

103

00:04:58,690  -->  00:05:01,010
Of course, do remember to put in your quotation marks.
104

104

00:05:01,010  -->  00:05:03,600
You will need them and your f-string.
105

105

00:05:03,600  -->  00:05:06,230
So now, we're going to print out this entire thing,
106

106

00:05:06,230  -->  00:05:08,630
Device printer, USB,
107

107

00:05:08,630  -->  00:05:12,283
and then we're gonna say remaining pages 100, or something.
108

108

00:05:13,240  -->  00:05:14,430
And finally, we're going to put
109

109

00:05:14,430  -->  00:05:18,043
in our printer specific method, which is the print method.
110

110

00:05:19,550  -->  00:05:20,470
Here, we're going to be able
111

111

00:05:20,470  -->  00:05:22,530
to print a certain number of pages.
112

112

00:05:22,530  -->  00:05:27,080
So we will say that if not self.connected,
113

113

00:05:27,080  -->  00:05:30,900
then we will print your printer is not connected.
114

114

00:05:30,900  -->  00:05:35,900
Otherwise, we're going to say print printing pages that,
115

115

00:05:35,950  -->  00:05:39,523
and then self.remaining pages-=pages.
116

116

00:05:40,360  -->  00:05:42,880
Of course, we do have to return here,
117

117

00:05:42,880  -->  00:05:45,640
so that we exit the function if we're not connected.
118

118

00:05:45,640  -->  00:05:48,270
Otherwise, we will print this and then that,
119

119

00:05:48,270  -->  00:05:49,990
which is not what we want.
120

120

00:05:49,990  -->  00:05:51,730
So, now we have our two classes;
121

121

00:05:51,730  -->  00:05:53,570
the printer and the device class.
122

122

00:05:53,570  -->  00:05:55,890
You can still use it, Device class on its own if you want.
123

123

00:05:55,890  -->  00:05:58,310
It's in no way related to the Printer class,
124

124

00:05:58,310  -->  00:06:01,460
so the Device class knows nothing about Printer.
125

125

00:06:01,460  -->  00:06:03,650
But the Printer class is related to the Device.
126

126

00:06:03,650  -->  00:06:06,770
It knows about it, it is the child of it.
127

127

00:06:06,770  -->  00:06:08,520
So, you can now create a printer and say
128

128

00:06:08,520  -->  00:06:13,520
Printer, printer, USB, and say 500 pages of capacity.
129

129

00:06:14,300  -->  00:06:18,890
And then, you can do printer.print and print 20 pages out,
130

130

00:06:18,890  -->  00:06:20,520
and then you can print your printer.
131

131

00:06:20,520  -->  00:06:21,580
This is all a bit confusing
132

132

00:06:21,580  -->  00:06:23,410
because I've gone for the name printer,
133

133

00:06:23,410  -->  00:06:25,770
which may not be the best one, but oh, well.
134

134

00:06:25,770  -->  00:06:27,420
So, we forgot an f-string here.
135

135

00:06:27,420  -->  00:06:28,660
Make sure to add that in.
136

136

00:06:28,660  -->  00:06:30,560
Then, we're gonna run it again.
137

137

00:06:30,560  -->  00:06:32,300
So, you get Printing 20 pages,
138

138

00:06:32,300  -->  00:06:36,550
and then your Device, printer, USB, 480 pages remaining.
139

139

00:06:36,550  -->  00:06:39,760
Here, we've used inheritance to build out our methods,
140

140

00:06:39,760  -->  00:06:42,350
like our init methods and our str method
141

141

00:06:42,350  -->  00:06:47,270
by using the parent-class-methods, such as here and here.
142

142

00:06:47,270  -->  00:06:49,170
In addition, this printer
143

143

00:06:50,360  -->  00:06:53,710
can still use the disconnect method
144

144

00:06:53,710  -->  00:06:56,220
that was defined in the Device class.
145

145

00:06:56,220  -->  00:06:59,030
And what happens when you do printer.disconnect
146

146

00:06:59,030  -->  00:07:02,690
is that Python will try to look for the disconnect method
147

147

00:07:02,690  -->  00:07:05,320
inside the Printer class.
148

148

00:07:05,320  -->  00:07:07,470
But upon not finding it,
149

149

00:07:07,470  -->  00:07:10,210
it will try to look in the next parent class,
150

150

00:07:10,210  -->  00:07:13,250
which is Device, and it will find it there.
151

151

00:07:13,250  -->  00:07:16,020
The Device class actually inherits from another class,
152

152

00:07:16,020  -->  00:07:18,480
as well, which is the Default inheritance,
153

153

00:07:18,480  -->  00:07:21,143
and that is Python's object class.
154

154

00:07:21,980  -->  00:07:26,310
So, if you call a method that is not in the Printer
155

155

00:07:26,310  -->  00:07:29,600
or the Device class, Python will then go to the Object class
156

156

00:07:29,600  -->  00:07:31,050
and see if it's there.
157

157

00:07:31,050  -->  00:07:33,660
And if it's not there, then you'll get an error.
158

158

00:07:33,660  -->  00:07:36,310
So those are the three levels of calling
159

159

00:07:36,310  -->  00:07:38,780
that you will see when you use the Printer class.
160

160

00:07:38,780  -->  00:07:40,590
First, the printer will be checked.
161

161

00:07:40,590  -->  00:07:42,210
Then, the Device will be checked.
162

162

00:07:42,210  -->  00:07:44,320
Finally, the object will be checked,
163

163

00:07:44,320  -->  00:07:46,360
and if none of them has the method
164

164

00:07:46,360  -->  00:07:48,060
or the property you're trying to access,
165

165

00:07:48,060  -->  00:07:49,650
then you'll get an error.
166

166

00:07:49,650  -->  00:07:51,000
Let me just run that,
167

167

00:07:51,000  -->  00:07:53,410
and you can see that you get disconnected there.
168

168

00:07:53,410  -->  00:07:56,230
Of course, if you do printer.print, and you try to print
169

169

00:07:56,230  -->  00:07:58,820
30 after you've disconnected,
170

170

00:07:58,820  -->  00:08:01,963
then you will see your printer is not connected.
171

171

00:08:02,950  -->  00:08:04,200
Hopefully, all of this makes sense.
172

172

00:08:04,200  -->  00:08:06,470
Inheritance in Python is much simpler
173

173

00:08:06,470  -->  00:08:08,280
than in other programming languages.
174

174

00:08:08,280  -->  00:08:11,850
All that happens is there is a hierarchy for calling things.
175

175

00:08:11,850  -->  00:08:14,010
When you try to call a method,
176

176

00:08:14,010  -->  00:08:15,920
or access a property of a class,
177

177

00:08:15,920  -->  00:08:19,610
that just goes up the hierarchy, and that's it.
178

178

00:08:19,610  -->  00:08:23,060
You can always use the Super class within a class.
179

179

00:08:23,060  -->  00:08:25,700
So, you can access that class' methods,
180

180

00:08:25,700  -->  00:08:28,140
such as what we're doing here and here.
181

181

00:08:28,140  -->  00:08:29,630
Thanks for joining me in this video.
182

182

00:08:29,630  -->  00:08:30,610
I hope you've enjoyed it,
183

183

00:08:30,610  -->  00:08:32,260
and I'll see you in the next one.
