When it comes to using classes in Python, and in most programming
languages, actually, we can inherit other classes, which
means we can use one class as a template for another class
and automatically inherit the goodies.
So we can actually really increase our reusability of any given class.
Now, a good example of this would be a class for 'cats' and
'dogs'. Now, cats and dogs are very different animals, but
they also have a lot of similarities.
For example, they both know how to speak.
They say something.
One says "Meow", one says, "Woof".
They have fur, most of them have fur.
The fur usually has some sort of color.
There are different sub species of cats and different variations of dogs.
And these are data points that sort of come together to create
a base class.
So what we're going to do, is create a class called 'Animal',
and in this class we need to instantiate this class with
specific attributes.
So let's give an animal a 'name'.
Let's say it always needs to have a name, just so, you know,
we can call it something.
And let's just assume we're using pets, not wild animals
here. And every animal needs a 'weight', because if it is a
thing, it probably has some weight.
So 'self.name =', whatever the 'name' is going to be, and
'self.weight =', whatever the 'weight' is going to be.
Now, every animal says something,
so let's give this a 'speak' method.
And this is just going to say, "What does the animal say?"
Because, I mean, it's a generic animal.
We don't know which animal we're talking about here.
We don't even know what the species is yet.
So we just have to implement something very generic.
So we have this generic 'Animal' class, and it comes with two
attributes, a 'name', and a 'weight', and a 'speak' method.
Now let's say we wanted to have a class for 'Cats'.
Well, we could copy and paste this whole thing.
Copy and paste, and the cat says, "Meow", and we could do that.
There's nothing really technically wrong with that,
but there is a nicer way. Because we're already using the
entire '__init__' method,
it's literally the exact same.
What we can do is let's go ahead and get rid of this,
and let's just inherit from 'Animal'.
This 'Animal' matches the name right there.
[no audio]
And so we use 'class', our new class name, an opening parentheses,
the class that we want to extend,
and if we had other classes, we could add other classes as well. We don't,
so we only have the one to inherit from, the closing parentheses
and then a ':', colon.
Now, honestly, at this point in time, we could just say 'pass',
and it's still going to ask us for a 'name' and a 'weight',
and when we do 'speak', it's going to say, "What does the animal say?"
So as an example, let's go ahead and say, 'henry =',
actually, I don't want that to be 'Cats', I want it to be 'Cat'.
'henry = Cat', and it's going to ask for a 'name'.
So the name is going to be "Henry", and his 'weight' is
going to be '9 lbs'.
And we have 'henry'.
We can actually even see that it is technically a 'Cat' class.
Now, in our 'Cat' class, we did nothing.
We just basically said, "Hey, inherit from 'Animal', but just
call it something different".
So this is actually a pointless example, which we'll build on in just a moment,
but this also is a good example in the sense that we have
all the '__init__' stuff within 'Cat' now.
And as an example, let's go ahead and get rid of this and just
try to instantiate the 'Cat' class without 'name', or 'weight',
and see the error that comes up.
We get a 'TypeError: missing 2 required
positional arguments: 'name' and 'weight'.
So let's go ahead,
let's undo that, and let's run 'henry.speak()'.
And 'henry' says, "What does the animal say?"
As far as I know, my little cat cannot speak human.
So we need to change that.
So let's go ahead and get rid of this 'pass', and let's overwrite
'speak'. Because 'Cat' inherits from 'Animal', it automatically
got the 'speak' method.
Now, that 'speak' method is not quite correct.
It's cool that we inherited it, but we needed to actually change it.
So we're going to overwrite this.
And it's going to say, "Meooowwww".
[no audio]
And when we rerun each cell, 'henry' now says, "Meooowwww".
Now to show you the difference here, let's instantiate a
regular 'Animal' class.
So the 'animal = Animal' class, and the 'name' is
"Ani", and the 'weight' is "100 lbs", because whatever animal
this is, it's big one. 'animal.', 'Tab', 'speak'.
And it says, "What does the animal say?"
So this actually has nothing to do with a 'Cat'
right now. The 'Cat' overwrote 'speak'.
It inherited from 'Animals',
so it originally said, "What does the animal say?"
And then we said, "No. No-No, that's not right.
Change it. Change it to, "Meooowwww".
But the 'Animal' class inherits from nothing.
It is just a base class,
and so by default, it has nothing to do with 'Cat'. Does not
really know that it exists.
And by default, it's 'speak' method is going to say, "What does the animal say?"
So now we're actually taking this, and applying this part
inside of it, and overwriting the 'speak' method.
Now, why is this useful?
Well, because we can do the same thing with a 'Dog' class.
'Dog' is going to inherit from an 'Animal', and we can do 'def
speak(): print("Woof woof")'.
[no audio]
And now we can say there is a dog, his name is 'veto'. Dog
his 'name' is "Veto", and his 'weight' is about "120 lbs".
Sure, we'll use an integer there.
'veto.', hit 'Tab', 'speak',
"Woof woof".
And so now what we've done, is we've really reused some of
our code here. We said, 'Animal' is just a base template.
We don't actually need to use it.
But because a 'Cat' and a 'Dog' do have similar things, such as
a 'name' and a 'weight', we don't have to write this inside
of the 'Cat' class.
We don't have to write it in there.
We also don't have to write inside of the 'Dog' class either.
And all we have to do is overwrite the things that we want to change.
It's a lot like cloning, science fiction cloning
anyways, where you have the person that you want to clone,
and then you're going to clone that person, and then
after that person is cloned, they're going to have different life
experiences. And because they have different life experiences,
they are going to eventually become their own
people. They're going to be a little bit different, but they will
still have certain things that are fundamentally the same.
And so this is basically how we clone, in a sense, classes in Python.
Now, what I would like you to do, is create a base class, and
then inherit that class, and instantiate the inherited class
with something that you've overwritten.
Much like what I've done in this video.