This lesson is from the Real Python video course by Austin Cepalia.
Inheritance Example
00:00 Welcome back to our series on object-oriented programming in Python. In the last video, we learned about the idea of inheritance, which allows us to define a child class that automatically inherits attributes and methods from its parent class.
00:15 Now, let’s see how inheritance works in action.
00:18
So, I’m here in Visual Studio Code, and the first thing we are going to do is define a new class called Person
. I’ll say here description = "general person"
, which will be our only class attribute.
00:33
Now, I’ll create our initializer method, and I’ll give it parameters of name
and age
. As usual, we’ll set the instance attributes equal to these parameters.
00:46
Now, I want to define a few behaviors that every person will have. I’ll create a new instance method called .speak()
with the only parameter being self
, and I’ll make this print out "My name is {} and I am {} years old"
. Then to fill in those gaps,
01:04
I’ll use the .format()
function and I’ll pass in self.name
and self.age
as arguments. Next, I want our person to be able to eat whatever food we give them.
01:14
So I’ll say here def eat(self, food):
,
01:21
and then I’ll print out "{} eats {}"
01:25
and to fill in those blanks ({}
), we’ll pass in self.name
as well as our food
parameter.
01:32
Lastly, let’s give our person the ability to perform an action. So, I’ll create one last instance method called .action()
, and when that’s called, I’ll say "{} jumps"
and I’ll pass in self.name
to fill in the blank.
01:49
All right. So now that we’ve got our general Person
class, let’s create a subclass called Baby
. To do this, I’ll type class Baby
, just like before, but then I’ll put in some parentheses (()
). Inside of these parentheses, we need to specify what the parent class of Baby
will be, so we’ll type in Person
. And now, technically, if I write pass
in the class body, then our Baby
will be usable but they’ll do the exact same thing as a Person
would, so we want to change that. First, I’ll redefine our .description
class attribute.
02:24
I’ll set it equal to something like "baby"
—that should work. This redefining here is called overriding because any Baby
object we create, will use this specific .description
instead of the .description
inherited automatically from the Person
class. To do this, I’ll type def speak()
with self
as the parameter, and then I’ll say print("ba ba ba ba ba")
, which is just some baby gibberish I came up with. This way, when we call the .speak()
method on a Baby
, it will say this gibberish instead of whatever the Parent
class would have said. Lastly, I want to give this Baby
some exclusive functionality.
03:06
Let’s give the baby the ability to nap whenever it wants, I’ll say def nap()
, with a parameter of self
, and then I’ll write print("{} takes a nap")
, and in place of the blank I’ll say self.name
. Now, any specific Baby
object we create will have the ability to nap, but a more general Person
object will not.
03:29
All we have to do is instantiate these classes and put them to work. I’ll create a new Person
object called person
, and he will have a name
of "Steve"
and an age
of 20
.
03:41
Then, I want to call all of the instance methods of the person
, so I’ll type person.speak()
and person.eat()
—and we’ll give him "pasta"
—and finally, person.action()
to see him jump.
03:58
Now, let’s create a Baby
object called baby
. So, I’ll type baby = Baby()
. And take a look at this: Visual Studio is telling
04:07
me that I need to supply a name
and an age
to the initializer for Baby
, but if you look, Baby
doesn’t actually have an initializer. That’s because it automatically inherited it from the Person
class.
04:21
Remember, this Baby
is also considered a Person
and as such, it needs to fill out the instance attributes of the Person
as well.
04:29
So we’ll give this Baby
a name
of "Ian"
and an age
of 1
. Then, we’re going to call the same instance methods on our Baby
object.
04:39
I’ll print out both the .description
of our person
and the .description
of our baby
. Before I run this, take a moment to pause the video and predict what the output will be.
04:51 So, I will right-click and choose Run Code and we get some console output.
04:57
We see: My name is Steve and I am 20 years old
, Steve eats pasta
, and Steve jumps
. Then, for our Baby
object, we see that the baby is speaking gibberish.
05:09
Finally, we can see that our Person
object has a class attribute of general person
, but our Baby
object has a class attribute of baby
.
05:19 This whole exercise shows us how we can define a child class, or a derived class, that automatically inherits everything from the parent class, or the base class.
05:28
We can override attributes and methods like .description
and .speak()
, and we can even extend our child class to add new functionality like we did with the .nap()
method. Just to make this even clearer, I’m going to move to a new line and type person
dot (.
).
05:45
If you remember, the dot (.
) is the access modifier, which allows us to access attributes and call methods on an object. Since this object is a Person
, notice how IntelliSense doesn’t see the .nap()
method.
05:58
That’s because it’s specific to the child class and as such, only child objects have it. However, if I delete this and I change this to baby
and I hit dot (.
), you can see that we have access to everything defined in the Person
class, as well as the specific .nap()
method.
06:17
But now, what if we’re told we need to make a change to the .action()
method? Maybe now we want both people to spin around instead of jumping.
06:26
Rather than having to modify code in several different classes, all we have to do now is change the word "jumps"
to the word "spins"
in our Person
class. Now, if we run this code, you’ll notice that both Steve and Ian are spinning instead of jumping, and we didn’t have to make a single modification to the Baby
class.
06:45
This is one of the reasons why inheritance is so powerful. Remember how earlier I said that behind the scenes, Python sees every object as the type object
? Well, now that we have our classes coded, I can show you that that’s true. To prove that Baby
is a Person
, I’ll print out the result of this special function called isinstance()
.
07:08
This function will tell us if a specific object is of a specific type. This function takes two arguments, so I will pass in the baby
object for the first, and I want to check if the baby
object is an instance of Person
.
07:23
If I run the code here, you’ll see that on the right side we see True
, and that’s because a baby is a person: the baby
object is of type Baby
, but also of type Person
because it inherits everything from the Person
class.
07:38
Now, let’s see if our baby
object is of type object
. I’ll change the word Person
here to lowercase object
, and if we run this code, we will see that our baby
is in fact an object
. That’s because Baby
is a Person
, and Person
inherits from object
. Therefore, Baby
inherits from object
, too.
07:59
Like I mentioned before, every class in Python inherits from object
, and we actually don’t even have to write that inside of the class declaration.
08:07
The reason for the object
class even existing is beyond the scope of this tutorial, but for now, just know that our Baby
objects are technically seen as a Baby
, a Person
, and an object
.
You must own this product to join the conversation.