Inheritance and polymorphism
Inheritance lets us create a new class from an existing one, and polymorphism lets us apply the same call to different objects. We examine both principles in Python examples.
All topics (2 of 2)
Inheritance means creating a new class on the basis of an existing one: the derived class (subclass) receives the attributes and methods of the base class and adds its own features. It expresses the “A is a kind of B” (is-a) relationship: a dog is a kind of animal, a circle is a kind of shape. Code is not duplicated, because the common part is written once in the base class.
In Python the base class is given in parentheses: class Dog(Animal):. In the constructor of the derived class, the base constructor must be called with super().__init__(name) so that the common attributes get set. When a derived class rewrites a method of the base class under the same name, this is called overriding: the method speak() in Dog gives a different result from the one in Animal.
Polymorphism (“many forms”) means that the same call works differently depending on the type of the object. For example, for a list of Dog and Cat objects the loop for a in animals: a.speak() runs each object’s own speak() method, and the loop does not need to change. So when a new class is added, the existing code keeps working unchanged. In Python any object that has the needed method fits, even without a common base class (duck typing).
Before using inheritance, check the relationship: can you say that an object of the derived class “is a kind of” the base class? If the relationship is “has a” (has-a), for example a car has an engine, composition is chosen instead of inheritance: one object is stored inside another. The check isinstance(d, Animal) returns True for an object d of class Dog.
Key takeaways
- Inheritance gives the derived class the attributes and methods of the base class and reduces code duplication.
- Inheritance is used for an is-a relationship; for has-a, composition is chosen.
- In a derived class constructor,
super().__init__(...)sets up the base class. - Overriding a method changes behavior in the derived class.
- Polymorphism makes the same call behave differently depending on the object’s type.
Practice tasks
- Write a base class
Animal(attributename, methodspeak()) and the classesDogandCatinheriting from it; let each overridespeak()in its own way. Make a list of animals “speak” with a single loop. - Create a base class
Shapeand the derived classesCircle(radiusr) andRectangle(w,h); implement anarea()method in each that computes the area, and find the total area of a list of different shapes. - Let the
Carclass store anEngineobject as composition (self.engine = Engine()); explain in writing why composition, not inheritance, is the right choice here.
Review questions
Test yourself: think first, then reveal the answer.
1When is composition chosen instead of inheritance?Show answerHide answer
When the relationship between classes is “has a” (a car has an engine) rather than “is a kind of”.2What is method overriding?Show answerHide answer
Implementing a base-class method differently in a derived class under the same name.3How does polymorphism simplify code?Show answerHide answer
The same call can be applied to objects of different classes, so adding a new type does not require changing chains of `if` conditions.
0 of 2 topics completed
Sign in to mark