1
00:00:00,960 --> 00:00:02,620
Hi guys, and welcome back!

2
00:00:02,620 --> 00:00:04,350
In this video, we're going to start talking

3
00:00:04,350 --> 00:00:06,780
about class inheritance.

4
00:00:06,780 --> 00:00:10,800
Inheritance allows one class to take some methods

5
00:00:10,800 --> 00:00:12,950
and properties from another class.

6
00:00:12,950 --> 00:00:14,660
Let's have a look.

7
00:00:14,660 --> 00:00:17,060
Imagine you've got a class called Device,

8
00:00:17,060 --> 00:00:20,150
such as a USB device or something like that.

9
00:00:20,150 --> 00:00:23,070
And you want it to represent just anything

10
00:00:23,070 --> 00:00:25,560
you might plug into your computer.

11
00:00:25,560 --> 00:00:27,720
So I'm going to define my init method,

12
00:00:27,720 --> 00:00:31,420
and then we're going to be able to give these devices names

13
00:00:31,420 --> 00:00:34,700
and how they are connected, such as by a USB.

14
00:00:34,700 --> 00:00:36,763
So I'll say, connected by.

15
00:00:37,670 --> 00:00:40,090
Then we'll say self.name=name,

16
00:00:40,090 --> 00:00:43,870
self.connected by=connected by,

17
00:00:43,870 --> 00:00:45,740
and we're also going to assume

18
00:00:45,740 --> 00:00:49,270
that when you create a device object,

19
00:00:49,270 --> 00:00:52,240
that is going to represent a connected device,

20
00:00:52,240 --> 00:00:54,690
something that is already connected to your computer.

21
00:00:54,690 --> 00:00:57,143
So we'll say self.connecte=true.

22
00:00:58,150 --> 00:01:00,690
We are going to assume that it's connected

23
00:01:00,690 --> 00:01:03,810
and we don't have to pass in a parameter for that.

24
00:01:03,810 --> 00:01:05,373
We can just say true here.

25
00:01:06,370 --> 00:01:11,370
Then, we will type str and we're gonna say return f

26
00:01:12,180 --> 00:01:16,390
device self.name, and we're going to put !r

27
00:01:17,730 --> 00:01:19,840
and we're gonna say self.connected_by.

28
00:01:19,840 --> 00:01:21,360
The exclamation mark r,

29
00:01:21,360 --> 00:01:25,300
calls the repr method of self.name,

30
00:01:25,300 --> 00:01:28,260
so that it shows up as having the quotes already.

31
00:01:28,260 --> 00:01:29,740
So this is just a little bit nicer

32
00:01:29,740 --> 00:01:31,060
than putting the quotes in yourself.

33
00:01:31,060 --> 00:01:34,880
Then we're also going to add a disconnect method,

34
00:01:34,880 --> 00:01:38,290
which just says self.connected=false

35
00:01:38,290 --> 00:01:40,570
and the prints out disconnected.

36
00:01:40,570 --> 00:01:43,580
So you have this class device here.

37
00:01:43,580 --> 00:01:45,580
This device doesn't do much at the moment,

38
00:01:45,580 --> 00:01:49,020
but you could do something like printer=device

39
00:01:49,020 --> 00:01:52,550
and call it Printer and say it's connected via USB,

40
00:01:52,550 --> 00:01:54,820
and then you can print it out.

41
00:01:54,820 --> 00:01:57,740
Finally, you can also disconnect it.

42
00:01:57,740 --> 00:01:59,390
All right, let's press play.

43
00:01:59,390 --> 00:02:02,740
And you can see that you get Device, Printer, USB,

44
00:02:02,740 --> 00:02:05,370
and then disconnected, so very good.

45
00:02:05,370 --> 00:02:09,560
Now, let's say you want to add functionality to this class

46
00:02:09,560 --> 00:02:13,130
that allows it to print things out.

47
00:02:13,130 --> 00:02:15,120
For example, it can print a certain number of pages,

48
00:02:15,120 --> 00:02:16,650
or something like that.

49
00:02:16,650 --> 00:02:20,930
This class here is not a printer, this is a device.

50
00:02:20,930 --> 00:02:23,260
Could be a printer, but it could also be a webcam,

51
00:02:23,260 --> 00:02:25,150
or a microphone, it could be anything.

52
00:02:25,150 --> 00:02:26,670
So we don't want to add

53
00:02:26,670 --> 00:02:30,570
printer specific functionality to this class.

54
00:02:30,570 --> 00:02:34,190
You could rename the class and turn it into a Printer class,

55
00:02:34,190 --> 00:02:36,740
but you can also create another class

56
00:02:36,740 --> 00:02:41,420
that uses all of these methods and has more,

57
00:02:41,420 --> 00:02:44,350
and that is where inheritance comes in.

58
00:02:44,350 --> 00:02:46,940
So we're going to create a printer class now,

59
00:02:46,940 --> 00:02:48,150
and we're going to do something new,

60
00:02:48,150 --> 00:02:50,750
which is put a pair of brackets after it,

61
00:02:50,750 --> 00:02:53,430
and here we're going to put Device.

62
00:02:53,430 --> 00:02:54,480
And what this tells Python

63
00:02:54,480 --> 00:02:56,670
is that you're creating a new class called Printer

64
00:02:56,670 --> 00:02:59,820
and it inherits from Device, which means that it will

65
00:02:59,820 --> 00:03:03,190
essentially copy and paste all of these methods.

66
00:03:03,190 --> 00:03:04,680
It won't quite do that,

67
00:03:04,680 --> 00:03:07,990
but you will be able to use these methods from this class.

68
00:03:07,990 --> 00:03:10,940
So, let's start by defining an init method.

69
00:03:10,940 --> 00:03:14,480
Now, this printer object is going to need a name,

70
00:03:14,480 --> 00:03:18,640
just like a device, e-connected by just like the device,

71
00:03:18,640 --> 00:03:21,850
and it's also going to have a capacity.

72
00:03:21,850 --> 00:03:24,280
How many pages left of ink?

73
00:03:24,280 --> 00:03:26,380
Then, what we're going to do is,

74
00:03:26,380 --> 00:03:28,690
instead of doing self.name=name,

75
00:03:28,690 --> 00:03:33,690
self.connect by=connected by, self.connected=true.

76
00:03:34,030 --> 00:03:35,210
Instead of doing that,

77
00:03:35,210 --> 00:03:37,910
which as you can see is a copy paste of this method here,

78
00:03:37,910 --> 00:03:42,820
we can just call the parent class device init method.

79
00:03:42,820 --> 00:03:47,053
So, what to do in Python 3, is to do super.init.

80
00:03:49,040 --> 00:03:52,440
So, super and then a pair of brackets,

81
00:03:52,440 --> 00:03:53,560
and what this does in Python

82
00:03:53,560 --> 00:03:56,760
is it gets the super class, or the parent class,

83
00:03:56,760 --> 00:03:58,600
which in this case is Device,

84
00:03:58,600 --> 00:04:02,300
and it's going to call the init method of that super class..

85
00:04:02,300 --> 00:04:06,260
Of course, the init-method needs a name and a connected by,

86
00:04:06,260 --> 00:04:08,850
so we would pass a name and connected by.

87
00:04:08,850 --> 00:04:10,260
These are two parameters.

88
00:04:10,260 --> 00:04:11,960
We still have capacity.

89
00:04:11,960 --> 00:04:15,550
So, we will say self.capacity=capacity

90
00:04:16,500 --> 00:04:20,260
and self.remaining pages=capacity.

91
00:04:20,260 --> 00:04:24,310
Why am I doing two properties with the same value?

92
00:04:24,310 --> 00:04:28,410
The capacity is the maximum amount of pages

93
00:04:28,410 --> 00:04:31,820
that a printer could potentially print, if it had full ink.

94
00:04:31,820 --> 00:04:34,280
Whereas the remaining pages is how many are left

95
00:04:34,280 --> 00:04:36,100
after printing some.

96
00:04:36,100 --> 00:04:38,340
So, you can think of this as maximum capacity

97
00:04:38,340 --> 00:04:39,933
and this as current capacity.

98
00:04:40,900 --> 00:04:43,793
Then, we are going to define an str method,

99
00:04:45,040 --> 00:04:47,160
and here we're going to return

100
00:04:48,070 --> 00:04:51,240
the super classes str method.

101
00:04:51,240 --> 00:04:56,240
And then we're also going to put in self.remaining pages,

102
00:04:56,560 --> 00:04:58,690
pages remaining, something like that.

103
00:04:58,690 --> 00:05:01,010
Of course, do remember to put in your quotation marks.

104
00:05:01,010 --> 00:05:03,600
You will need them and your f-string.

105
00:05:03,600 --> 00:05:06,230
So now, we're going to print out this entire thing,

106
00:05:06,230 --> 00:05:08,630
Device printer, USB,

107
00:05:08,630 --> 00:05:12,283
and then we're gonna say remaining pages 100, or something.

108
00:05:13,240 --> 00:05:14,430
And finally, we're going to put

109
00:05:14,430 --> 00:05:18,043
in our printer specific method, which is the print method.

110
00:05:19,550 --> 00:05:20,470
Here, we're going to be able

111
00:05:20,470 --> 00:05:22,530
to print a certain number of pages.

112
00:05:22,530 --> 00:05:27,080
So we will say that if not self.connected,

113
00:05:27,080 --> 00:05:30,900
then we will print your printer is not connected.

114
00:05:30,900 --> 00:05:35,900
Otherwise, we're going to say print printing pages that,

115
00:05:35,950 --> 00:05:39,523
and then self.remaining pages-=pages.

116
00:05:40,360 --> 00:05:42,880
Of course, we do have to return here,

117
00:05:42,880 --> 00:05:45,640
so that we exit the function if we're not connected.

118
00:05:45,640 --> 00:05:48,270
Otherwise, we will print this and then that,

119
00:05:48,270 --> 00:05:49,990
which is not what we want.

120
00:05:49,990 --> 00:05:51,730
So, now we have our two classes;

121
00:05:51,730 --> 00:05:53,570
the printer and the device class.

122
00:05:53,570 --> 00:05:55,890
You can still use it, Device class on its own if you want.

123
00:05:55,890 --> 00:05:58,310
It's in no way related to the Printer class,

124
00:05:58,310 --> 00:06:01,460
so the Device class knows nothing about Printer.

125
00:06:01,460 --> 00:06:03,650
But the Printer class is related to the Device.

126
00:06:03,650 --> 00:06:06,770
It knows about it, it is the child of it.

127
00:06:06,770 --> 00:06:08,520
So, you can now create a printer and say

128
00:06:08,520 --> 00:06:13,520
Printer, printer, USB, and say 500 pages of capacity.

129
00:06:14,300 --> 00:06:18,890
And then, you can do printer.print and print 20 pages out,

130
00:06:18,890 --> 00:06:20,520
and then you can print your printer.

131
00:06:20,520 --> 00:06:21,580
This is all a bit confusing

132
00:06:21,580 --> 00:06:23,410
because I've gone for the name printer,

133
00:06:23,410 --> 00:06:25,770
which may not be the best one, but oh, well.

134
00:06:25,770 --> 00:06:27,420
So, we forgot an f-string here.

135
00:06:27,420 --> 00:06:28,660
Make sure to add that in.

136
00:06:28,660 --> 00:06:30,560
Then, we're gonna run it again.

137
00:06:30,560 --> 00:06:32,300
So, you get Printing 20 pages,

138
00:06:32,300 --> 00:06:36,550
and then your Device, printer, USB, 480 pages remaining.

139
00:06:36,550 --> 00:06:39,760
Here, we've used inheritance to build out our methods,

140
00:06:39,760 --> 00:06:42,350
like our init methods and our str method

141
00:06:42,350 --> 00:06:47,270
by using the parent-class-methods, such as here and here.

142
00:06:47,270 --> 00:06:49,170
In addition, this printer

143
00:06:50,360 --> 00:06:53,710
can still use the disconnect method

144
00:06:53,710 --> 00:06:56,220
that was defined in the Device class.

145
00:06:56,220 --> 00:06:59,030
And what happens when you do printer.disconnect

146
00:06:59,030 --> 00:07:02,690
is that Python will try to look for the disconnect method

147
00:07:02,690 --> 00:07:05,320
inside the Printer class.

148
00:07:05,320 --> 00:07:07,470
But upon not finding it,

149
00:07:07,470 --> 00:07:10,210
it will try to look in the next parent class,

150
00:07:10,210 --> 00:07:13,250
which is Device, and it will find it there.

151
00:07:13,250 --> 00:07:16,020
The Device class actually inherits from another class,

152
00:07:16,020 --> 00:07:18,480
as well, which is the Default inheritance,

153
00:07:18,480 --> 00:07:21,143
and that is Python's object class.

154
00:07:21,980 --> 00:07:26,310
So, if you call a method that is not in the Printer

155
00:07:26,310 --> 00:07:29,600
or the Device class, Python will then go to the Object class

156
00:07:29,600 --> 00:07:31,050
and see if it's there.

157
00:07:31,050 --> 00:07:33,660
And if it's not there, then you'll get an error.

158
00:07:33,660 --> 00:07:36,310
So those are the three levels of calling

159
00:07:36,310 --> 00:07:38,780
that you will see when you use the Printer class.

160
00:07:38,780 --> 00:07:40,590
First, the printer will be checked.

161
00:07:40,590 --> 00:07:42,210
Then, the Device will be checked.

162
00:07:42,210 --> 00:07:44,320
Finally, the object will be checked,

163
00:07:44,320 --> 00:07:46,360
and if none of them has the method

164
00:07:46,360 --> 00:07:48,060
or the property you're trying to access,

165
00:07:48,060 --> 00:07:49,650
then you'll get an error.

166
00:07:49,650 --> 00:07:51,000
Let me just run that,

167
00:07:51,000 --> 00:07:53,410
and you can see that you get disconnected there.

168
00:07:53,410 --> 00:07:56,230
Of course, if you do printer.print, and you try to print

169
00:07:56,230 --> 00:07:58,820
30 after you've disconnected,

170
00:07:58,820 --> 00:08:01,963
then you will see your printer is not connected.

171
00:08:02,950 --> 00:08:04,200
Hopefully, all of this makes sense.

172
00:08:04,200 --> 00:08:06,470
Inheritance in Python is much simpler

173
00:08:06,470 --> 00:08:08,280
than in other programming languages.

174
00:08:08,280 --> 00:08:11,850
All that happens is there is a hierarchy for calling things.

175
00:08:11,850 --> 00:08:14,010
When you try to call a method,

176
00:08:14,010 --> 00:08:15,920
or access a property of a class,

177
00:08:15,920 --> 00:08:19,610
that just goes up the hierarchy, and that's it.

178
00:08:19,610 --> 00:08:23,060
You can always use the Super class within a class.

179
00:08:23,060 --> 00:08:25,700
So, you can access that class' methods,

180
00:08:25,700 --> 00:08:28,140
such as what we're doing here and here.

181
00:08:28,140 --> 00:08:29,630
Thanks for joining me in this video.

182
00:08:29,630 --> 00:08:30,610
I hope you've enjoyed it,

183
00:08:30,610 --> 00:08:32,260
and I'll see you in the next one.

