Using Abstract Base Classes: Code
00:00
So the goal here is to create an ABC called Vehicle
that defines the required interface that you need and makes all your vehicle classes inherit from it.
00:09
First, you need to import ABC
, and abstractmethod
from the abc
module. from abc import ABC
, all letters capitalized, and abstractmethod
.
00:24
Then you need to define your base class: class
Vehicle(ABC)
. Then you can initialize the required attributes using the __init__
magic method.
00:36
Moving this method to the base class saves you from repetitive code in your subclasses. def
__init__(self,
make, model, color):
self.make = make
self.model = model
and self.color = color
.
01:04
Now for the .start
, .stop
, and .drive
methods, you need to define the required methods as abstract methods. You can use the abstractmethod
decorator that you imported earlier.
01:16
Note that the abstract methods don’t provide a specific implementation. They just raise NotImplementedError
exceptions. So @abstractmethod def
let’s start with start(self):
01:36
and you will raise NotImplementedError
you can say ("Start
must be implemented.")
01:51
So when you’re creating a class without the needed methods, right away you’ll get an error. Okay, let’s do the same thing for stop and drive. @abstract method
def stop(self): raise
NotImplementedError
, I can say stop()
must be implemented
.
02:21
And exactly the same thing for drive: @abstract method
02:32
raise,
NotImplemented` Error drive()
must be implemented
.
02:44 Okay, this is your base class. You can save it. And also one thing to look out for is that you can instantiate an ABC directly. They work as an API template for other classes to adhere to.
03:00
Let’s actually try this out in the terminal. Let’s say from vehicle_abc import Vehicle
. Okay? And then let’s try to just instantiate from Vehicle
.
03:12
So Vehicle("Ford", "Mustang", "Red")
. Okay? When you run this code, you get a type error. You can’t instantiate abstract class Vehicle
with abstract methods drive
, start
, and stop
. Okay?
03:26
So you need to create subclasses. Okay, back to the code. Now you’re creating specific vehicles by inheriting from the Vehicle
class and implementing all the required methods.
03:40
It’s actually almost the same code as duck typing, but now you’re inheriting from your Vehicle
ABC. So class Car(Vehicle):
03:57
and then you’re printing, “The car is starting.” And you’re going to do the same thing for stop
and drive
, and you’re going to do Truck
and add start
, stop
, and drive
.
04:10 Okay? So it’ll look like this and you’re done. You’ve replaced duck typing with ABCs. And please note that in this case, your classes are coupled with the base class.
04:24
This can be a limitation because you won’t be able to reuse one of your classes in a different project unless you also take the Vehicle
class with you.
04:33
Okay? Now, let’s create a Jeep
class that inherits from Vehicle
without providing the required interface. Let’s see what happens. class
Jeep(Vehicle):
04:49
Okay, let’s just say def
start(self):
and say print("The Jeep is starting.")
and let’s just keep it like this. Let’s not implement drive
and stop
.
05:01
Okay? Let’s see what happens. And then let’s say jeep = Jeep(
"Land Rover", "Defender",
and
05:13
"Black")
. As you probably remember, these are the make model and color of the car. And let’s try and see what happens. You get a type error, `Can’t instantiate abstract class Jeep with abstract methods drive, stop.
05:31
Basically, you just need to implement drive
and stop
, and this is exactly the type of error we were looking for. What happened here was that you only implemented the start
method, which doesn’t fulfill the complete interface.
05:43 When you try to instantiate this class, you get a type error because the required interface is incomplete. This behavior is exactly why ABCs are important because they enforce specific interfaces.
Become a Member to join the conversation.