Inheritance is one of the core topic of object oriented programming. It comes handy in a lot of scenarios while designing or developing a complex software. Python supports inheritance with an use of a minimum number of syntax and semantics.
Inheritance is the mechanism of inheriting the properties and methods of an existing class. The inherited class can add more methods and or properties of its own. The class which is used as basis for inheritance is called the base class
or parent class
or super class
. On the other hand, the class that inherits from the parent class is called the child class
or subclass
or derived class
.
Let's see an example of inheritance:
class Animal:
def eat(self):
print("It eats.")
def sleep(self):
print("It sleeps.")
class Bird(Animal):
def fly(self):
print("It flies in the sky.")
def sing(self):
print("It sings.")
print(issubclass(Bird, Animal))
duck = Bird()
print(isinstance(duck, Bird))
duck.eat()
duck.sleep()
duck.fly()
duck.sing()
Here Bird
class inherits the Animal
class. So, Animal
is the parent class (also known as super class or base class) and Bird
is the child class (also known as sub class or derived class). The issubclass
method ensures that Bird
is a subclass of Animal
class.
Then we created an instance of Bird class called duck
. In this case, the isinstance
method ensures that duck
is an instance of Bird
class. We called the methods of Animal
class to check if they are inherited in Bird
class. Each animal eats and sleeps. Birds are also animals. So, they inherited the properties of animals. On the contrary, only birds can fly and sing. These two characteristics distinguish them from other animals.
Now, let's help the birds to sing their songs. Install a Python package called pyttsx3
to give life to the bird.
You can simply install the package using pip install pyttsx3
.
After installing the package, we are going to create a new file called speaker.py
which includes a single class named Speaker
. This class will convert any text to sound. The speaker.py
contains:
import pyttsx3
class Speaker:
engine = pyttsx3.init()
def speak(self, text = "No sound is found."):
print(text)
self.engine.say(text)
self.engine.runAndWait()
Then, add another class called SingingBird
that inherits both Bird
class and Speaker
class in our case study example. It is called Multiple Inheritance. Update the previous code as follow:
from speaker import Speaker
class Animal:
def eat(self):
print("It eats.")
def sleep(self):
print("It sleeps.")
class Bird(Animal):
def fly(self):
print("It flies in the sky.")
def sing(self):
print("It sings.")
def speak(self, text = "No sound is found."):
print("It can not speak but can write it.")
print(text)
class SingingBird(Speaker, Bird):
def __init__(self, birdName = "Bird Name"):
self.birdName = birdName
def printBirdName(self):
print("This is a {birdName}!".format(birdName = self.birdName))
print(SingingBird.__bases__)
duck = SingingBird("Duck")
duck.printBirdName()
duck.eat()
duck.sleep()
duck.fly()
duck.sing()
duck.speak("Quack quack, quack quack, quack quack")
The output looks like:
(<class '__main__.Bird'>, <class 'speaker.Speaker'>)
This is a Duck!
It eats.
It sleeps.
It flies in the sky.
It sings.
Quack quack, quack quack, quack quack
The __bases__
attribute of SingingBird
shows (<class '__main__.Bird'>, <class '__main__.Speaker'>)
which ensures the multiple inheritance of that class. So, we see that Python supports Multiple Inheritance
like a charm.
We see that speak
method exists in both Bird
and Speaker
class. As SingingBird
inherits both Bird
class and Speaker
class, why speak
method of Speaker
class is being invoked? The answer is SingingBird
invokes the first speak
method of it's base classes. If a method is implemented differently by two or more of the super classes, the order of the class method should be maintained.
The methods in the earlier classes override the methods in later ones. So, if we create SingingBird
like class SingingBird(Bird, Speaker)
it would override (making the bird mute!) the speak
method of the Speaker
class. Reversing their order like this: class SingingBird(Speaker, Bird)
would make the speak
method of Speaker
class accessible.
All codes can be found in this gist.
Thanks to David Griffin for giving vital suggestions to improve this post.
Top comments (5)
I know this is a trivial example, but for the love of anything, don't import inside functions! Inside a function you'll be executing the import statement every time the function is called, which is generally agreed to be A Bad Thing ®.
Incidentally, while I'm unfamiliar with the library, it seems pretty likely that the code would be better performing with a global initialisation of pyttsx3 and engine as a global variable (if you had multiple ducks, obviously), but that's comparatively minor.
Unlike Java, Python modules aren't imported multiple times. Just running import two times will not reload the module. In this scenario, we could create two files; one for
Speaker
class and another for other classes. InSpeaker
class we could load the module at the top. But for simplicity of explaining theinheritance
which is the core subject of the tutorial, I have merged them in a single file. But this operation will not effect the performance or reload thepyttsx3
as I mentioned earlier. Thank you for pointing out a nice feature of Python.While I was referring to best practices in programming (and remember, Python's style guide explicitly states where imports should go), with the view that best practice is absolutely something we should follow while teaching newcomers, the claim of performance being identical is demonstrably false.
So, point of fact, import is actually a pretty expensive operation; it's 6 times more expensive than simple bytecode ops, and three times more expensive than a function call.
Updated the post to follow the best practices. Thank you a lot for pointing out those. Really appreciate your explanation and effort.
In our case, we did not need to create an object of
Speaker
class. But this did not make it an abstract class. In Python to declare a class as abstract class, we need to useabc
module. Here is the official documentation on Abstract Base Classes in Python