WEBVTT 1 00:00:00.240 --> 00:00:02.335 Hi, welcome back. 2 00:00:02.335 --> 00:00:05.280 In this video we're going to talk quickly about ABCs. 3 00:00:06.130 --> 00:00:08.811 ABCs are pretty useful in Python 4 00:00:08.811 --> 00:00:13.010 because they let you define some functionality 5 00:00:13.010 --> 00:00:14.320 without implementing it. 6 00:00:15.300 --> 00:00:19.331 We're going to leave our users and admins for a moment 7 00:00:19.331 --> 00:00:22.650 and create a new file that I'm going to call, 8 00:00:22.650 --> 00:00:24.220 "Animals" 9 00:00:24.220 --> 00:00:27.970 and this is going to be maybe a not great example 10 00:00:27.970 --> 00:00:30.727 on using ABCs in a real project 11 00:00:30.727 --> 00:00:34.580 but just a quick overview of how they work 12 00:00:34.580 --> 00:00:37.900 then we're going to use ABCs on the rest of our code. 13 00:00:38.800 --> 00:00:42.530 So, let's say we've got a class Dog, 14 00:00:42.530 --> 00:00:43.370 for example 15 00:00:44.990 --> 00:00:45.823 and this, 16 00:00:45.823 --> 00:00:47.730 you can initialise it with, 17 00:00:47.730 --> 00:00:49.170 let's say, a name 18 00:00:51.420 --> 00:00:54.621 and there is something that all dogs 19 00:00:54.621 --> 00:00:57.930 or at least a large majority of them have in common 20 00:00:57.930 --> 00:00:59.590 which is the number of legs, 21 00:00:59.590 --> 00:01:00.423 let's say. 22 00:01:03.780 --> 00:01:04.613 In a Dog, 23 00:01:04.613 --> 00:01:07.780 let's say that this is going to return four at all times. 24 00:01:10.480 --> 00:01:13.620 So, not the most useful method for any class, 25 00:01:13.620 --> 00:01:16.500 this might as well be a property of the Dog 26 00:01:16.500 --> 00:01:19.230 or maybe a class variable there 27 00:01:19.230 --> 00:01:22.340 but none the less let's define it as this method. 28 00:01:24.450 --> 00:01:27.180 Now, if you wanted to define another class, 29 00:01:28.072 --> 00:01:30.470 let's say a Monkey 30 00:01:32.550 --> 00:01:33.780 that also has, 31 00:01:33.780 --> 00:01:34.830 let's say, a name 32 00:01:35.763 --> 00:01:38.390 and also has a num_legs, 33 00:01:39.930 --> 00:01:41.480 let's say that now returns two. 34 00:01:42.790 --> 00:01:47.400 You've got a bit of a problem. 35 00:01:47.400 --> 00:01:50.750 Before we said you can extract functionality 36 00:01:51.960 --> 00:01:53.600 into a class like 37 00:01:55.150 --> 00:01:56.620 some Animal class 38 00:01:56.620 --> 00:01:59.630 and define some functionality here 39 00:01:59.630 --> 00:02:01.400 and then return something 40 00:02:01.400 --> 00:02:02.900 and then you could make the Dog 41 00:02:02.900 --> 00:02:04.370 extend from Animal 42 00:02:05.800 --> 00:02:07.750 and then you could delete this method 43 00:02:07.750 --> 00:02:09.760 but you cannot do the same with the Monkey 44 00:02:09.760 --> 00:02:12.400 because the Monkey has two legs not four. 45 00:02:13.570 --> 00:02:15.420 So, how do you do this? 46 00:02:16.551 --> 00:02:19.510 Well, here's where ABCs come into play. 47 00:02:20.560 --> 00:02:22.520 Let's say that you have a bit more functionality 48 00:02:22.520 --> 00:02:24.510 for each animal that you want 49 00:02:24.510 --> 00:02:26.500 to make available to an Animal. 50 00:02:26.500 --> 00:02:28.714 Let's say for example a walk method 51 00:02:28.714 --> 00:02:31.699 and this walk method that is going to return 52 00:02:31.699 --> 00:02:33.936 or print 'Walking...', 53 00:02:33.936 --> 00:02:37.130 of course this could be something a bit more useful 54 00:02:37.130 --> 00:02:39.184 in a real programme but now that is just an example. 55 00:02:39.184 --> 00:02:42.191 Now you want both your Monkey and your Dog 56 00:02:42.191 --> 00:02:44.860 to extend from Animal so that they 57 00:02:44.860 --> 00:02:47.036 can both use this method walk 58 00:02:47.036 --> 00:02:50.338 but you don't want the num_legs method 59 00:02:50.338 --> 00:02:53.000 to be four for both animals. 60 00:02:54.040 --> 00:02:57.670 So, what to do is to cut it again, 61 00:02:58.550 --> 00:02:59.383 oh by the way, 62 00:02:59.383 --> 00:03:02.020 let me just say this would do what you want. 63 00:03:02.020 --> 00:03:03.680 This current status of the code, 64 00:03:03.680 --> 00:03:06.056 defining num_legs in the Animal class, 65 00:03:06.056 --> 00:03:08.070 the dog would inherit that Animal 66 00:03:08.070 --> 00:03:09.550 and it would return four. 67 00:03:09.550 --> 00:03:11.520 The Monkey would override the method 68 00:03:11.520 --> 00:03:12.353 and would return two, 69 00:03:12.353 --> 00:03:13.280 so this works 70 00:03:13.280 --> 00:03:15.460 but there is a problem 71 00:03:15.460 --> 00:03:17.323 which is that you can now 72 00:03:17.323 --> 00:03:18.583 say that, 73 00:03:18.583 --> 00:03:21.110 you can create a new Animal 74 00:03:22.880 --> 00:03:26.098 and then you can print a.num_legs 75 00:03:26.098 --> 00:03:28.620 and that's just kind of weird 76 00:03:28.620 --> 00:03:31.247 because not all animals have four legs 77 00:03:31.247 --> 00:03:32.863 but if you run this file, 78 00:03:32.863 --> 00:03:37.863 you'll see that your Animal class 79 00:03:38.270 --> 00:03:40.260 that isn't a specific animal, 80 00:03:40.260 --> 00:03:42.270 it's not a Dog or a Monkey or a Cat, 81 00:03:42.270 --> 00:03:44.983 it's just this abstract Animal class 82 00:03:44.983 --> 00:03:47.280 returns four for the number of legs 83 00:03:47.280 --> 00:03:48.120 which doesn't make any sense 84 00:03:48.120 --> 00:03:51.868 because animals don't always have four legs. 85 00:03:51.868 --> 00:03:53.512 So what to do is 86 00:03:53.512 --> 00:03:56.920 to cut that and put it back into the Dog. 87 00:03:58.953 --> 00:03:59.880 Now of course, 88 00:03:59.880 --> 00:04:01.410 if we say a is Animal 89 00:04:01.410 --> 00:04:03.260 and print a.num_legs, 90 00:04:03.260 --> 00:04:04.410 it gives an error because it says, 91 00:04:04.410 --> 00:04:05.710 I don't know what that is. 92 00:04:06.850 --> 00:04:10.620 So, that's fine but if you have 93 00:04:10.620 --> 00:04:11.940 a Dog and Monkey 94 00:04:11.940 --> 00:04:15.280 and potentially let's say a Whale. 95 00:04:18.239 --> 00:04:21.610 The Whale will have some code here 96 00:04:22.580 --> 00:04:24.370 and the Monkey will have some code in here 97 00:04:24.370 --> 00:04:26.930 and the Dog will have some code in here 98 00:04:26.930 --> 00:04:29.280 and just by looking at the class 99 00:04:29.280 --> 00:04:30.930 and the inheritance tree, 100 00:04:30.930 --> 00:04:34.880 you don't know whether they have a num_legs or not. 101 00:04:36.240 --> 00:04:38.810 The Whale should probably not have num_legs 102 00:04:39.650 --> 00:04:41.280 or perhaps it should be 0. 103 00:04:41.280 --> 00:04:43.520 Maybe Whales should not inherit from Animal 104 00:04:43.520 --> 00:04:45.480 it should inherit from something else. 105 00:04:45.480 --> 00:04:48.690 So, what I mean to say is just by knowing 106 00:04:48.690 --> 00:04:49.970 that these two are Animals, 107 00:04:49.970 --> 00:04:52.623 you don't know they have num_legs 108 00:04:52.623 --> 00:04:56.246 but it could be interesting for you to know that, 109 00:04:56.246 --> 00:04:59.750 so here comes the ABCs, 110 00:04:59.750 --> 00:05:04.620 let's do from ABC import ABCMeta and abstractmethod 111 00:05:06.160 --> 00:05:07.749 and then we're going to 112 00:05:07.749 --> 00:05:10.176 make our Animal class inherit 113 00:05:10.176 --> 00:05:14.070 but in a slightly different way from ABCMeta. 114 00:05:15.400 --> 00:05:18.566 Now, ABCMeta is a real class 115 00:05:18.566 --> 00:05:21.970 but it allows us to some things 116 00:05:21.970 --> 00:05:23.980 that normal classes don't allow us to do 117 00:05:23.980 --> 00:05:27.520 and that's using this abstractmethod. 118 00:05:27.520 --> 00:05:29.120 Now, one of the great things 119 00:05:29.120 --> 00:05:31.250 of having this abstract base class, 120 00:05:31.250 --> 00:05:32.380 this is what ABC mean, 121 00:05:32.380 --> 00:05:34.620 abstract base class, 122 00:05:34.620 --> 00:05:36.792 is we can do abstractmethod 123 00:05:36.792 --> 00:05:40.330 and then define our num_legs method 124 00:05:42.656 --> 00:05:44.760 and then do something like pass. 125 00:05:48.430 --> 00:05:51.270 Okay, so now we've defined this abstractmethod 126 00:05:51.270 --> 00:05:55.220 and we've said Animal has this method, 127 00:05:55.220 --> 00:06:00.220 num_legs but it's not about a specific animal in the world 128 00:06:00.650 --> 00:06:02.680 its a bit abstract, 129 00:06:02.680 --> 00:06:05.806 it doesn't refer to anything concrete, 130 00:06:05.806 --> 00:06:09.090 so then it is the responsibility of the child classes, 131 00:06:09.090 --> 00:06:12.765 like Dog and Monkey to implement that method. 132 00:06:12.765 --> 00:06:15.610 Now, if we run this code, 133 00:06:15.610 --> 00:06:17.230 if we run Animals, 134 00:06:17.230 --> 00:06:18.759 we get an error and it says, 135 00:06:18.759 --> 00:06:21.866 "Can't instantiate abstract class Animals 136 00:06:21.866 --> 00:06:25.320 "with abstract methods num_legs." 137 00:06:25.320 --> 00:06:27.550 Python doesn't let you create an object 138 00:06:27.550 --> 00:06:29.620 of type Animal anymore 139 00:06:29.620 --> 00:06:32.408 because it realises that an Animal isn't a thing 140 00:06:32.408 --> 00:06:34.050 in your programme, 141 00:06:34.050 --> 00:06:36.140 an animal is something that you've used 142 00:06:36.140 --> 00:06:39.665 to extract functionality and give you a bit of information 143 00:06:39.665 --> 00:06:40.900 but it's not something 144 00:06:40.900 --> 00:06:42.900 that you want to interact with directly. 145 00:06:43.840 --> 00:06:47.061 So, it doesn't let you instantiate an Animal class 146 00:06:47.061 --> 00:06:50.280 because it doesn't make sense to do that. 147 00:06:50.280 --> 00:06:52.260 You instantiate specific animals, 148 00:06:52.260 --> 00:06:53.600 like Dogs or Monkeys 149 00:06:55.280 --> 00:06:58.420 so this is how you use an ABC, 150 00:06:58.420 --> 00:07:00.410 an abstract base class 151 00:07:00.410 --> 00:07:03.220 and how you define an abstractmethod. 152 00:07:03.220 --> 00:07:05.520 If any of your subclasses don't implement 153 00:07:05.520 --> 00:07:06.520 to the abstractmethod, 154 00:07:06.520 --> 00:07:09.860 you won't be able to create objects either, 155 00:07:09.860 --> 00:07:13.830 so if you delete this from the Dog class 156 00:07:13.830 --> 00:07:15.290 and then try to create a Dog 157 00:07:21.270 --> 00:07:23.110 and then you print num_legs, 158 00:07:24.670 --> 00:07:26.390 it won't let you, 159 00:07:26.390 --> 00:07:27.500 so let's delete that, 160 00:07:27.500 --> 00:07:29.020 run Animals again 161 00:07:29.020 --> 00:07:30.582 and it says you can't do that 162 00:07:30.582 --> 00:07:35.110 but as soon as you have this method in here 163 00:07:37.450 --> 00:07:38.283 and you run it, 164 00:07:38.283 --> 00:07:40.240 now you can and you get four back. 165 00:07:41.840 --> 00:07:44.370 So, abstract base classes can be quite useful 166 00:07:44.370 --> 00:07:46.610 in a number of scenarios 167 00:07:46.610 --> 00:07:50.170 in order for you to know that the sub classes 168 00:07:50.170 --> 00:07:51.952 will all have this method. 169 00:07:51.952 --> 00:07:56.130 So you know when ever you have a sub class of type Animal 170 00:07:56.130 --> 00:07:58.082 this method will be available. 171 00:07:58.082 --> 00:08:01.789 Let's expand a little bit on why this is useful 172 00:08:01.789 --> 00:08:04.690 in the very next video. 173 00:08:04.690 --> 00:08:05.740 I will see you there.