Skip to main content

How To Code in Python 3: How To Apply Polymorphism to Classes

How To Code in Python 3
How To Apply Polymorphism to Classes
    • Notifications
    • Privacy
  • Project HomeHow To Code in Python 3
  • Projects
  • Learn more about Manifold

Notes

Show the following:

  • Annotations
  • Resources
Search within:

Adjust appearance:

  • font
    Font style
  • color scheme
  • Margins
table of contents
  1. Introduction
  2. Python 2 vs Python 3: Practical Considerations
  3. How To Install Python 3 and Set Up a Local Programming Environment on Ubuntu 16.04
  4. How To Install Python 3 and Set Up a Local Programming Environment on macOS
  5. How To Install Python 3 and Set Up a Local Programming Environment on Windows 10
  6. How To Install Python 3 and Set Up a Local Programming Environment on CentOS 7
  7. How To Install Python 3 and Set Up a Programming Environment on an Ubuntu 16.04 Server
  8. How To Write Your First Python 3 Program
  9. How To Work with the Python Interactive Console
  10. How To Write Comments
  11. Understanding Data Types
  12. An Introduction to Working with Strings
  13. How To Format Text
  14. An Introduction to String Functions
  15. How To Index and Slice Strings
  16. How To Convert Data Types
  17. How To Use Variables
  18. How To Use String Formatters
  19. How To Do Math with Operators
  20. Built-in Python 3 Functions for Working with Numbers
  21. Understanding Boolean Logic
  22. Understanding Lists
  23. How To Use List Methods
  24. Understanding List Comprehensions
  25. Understanding Tuples
  26. Understanding Dictionaries
  27. How To Import Modules
  28. How To Write Modules
  29. How To Write Conditional Statements
  30. How To Construct While Loops
  31. How To Construct For Loops
  32. How To Use Break, Continue, and Pass Statements when Working with Loops
  33. How To Define Functions
  34. How To Use *args and **kwargs
  35. How To Construct Classes and Define Objects
  36. Understanding Class and Instance Variables
  37. Understanding Inheritance
  38. How To Apply Polymorphism to Classes
  39. How To Use the Python Debugger
  40. How To Debug Python with an Interactive Console
  41. How To Use Logging
  42. How To Port Python 2 Code to Python 3

How To Apply Polymorphism to Classes

Polymorphism is the ability to leverage the same interface for different underlying forms such as data types or classes. This permits functions to use entities of different types at different times.

For object-oriented programming in Python, this means that a particular object belonging to a particular class can be used in the same way as if it were a different object belonging to a different class.

Polymorphism allows for flexibility and loose coupling so that code can be extended and easily maintained over time.

This tutorial will go through applying polymorphism to classes in Python.

What Is Polymorphism?

Polymorphism is an important feature of class definition in Python that is utilized when you have commonly named methods across classes or subclasses. This allows functions to use objects of any of these polymorphic classes without needing to be aware of distinctions across the classes.

Polymorphism can be carried out through inheritance, with subclasses making use of base class methods or overriding them.

Python’s duck typing, a special case of dynamic typing, uses techniques characteristic of polymorphism, including late binding and dynamic dispatch. The term “duck typing” is derived from a quote of writer James Whitcomb Riley: “When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.” Appropriated by Italian computer engineer Alex Martelli in a message to the comp.lang.python newsgroup, the use of duck typing is concerned with establishing the suitability of an object for a specific purpose. When using normal typing this suitability is determined by the type of an object alone, but with duck typing the presence of methods and properties are used to determine suitability rather than the actual type of the object in question. That is to say, you check whether the object quacks like a duck and walks like a duck rather than asking whether the object is a duck.

When several classes or subclasses have the same method names, but different implementations for these same methods, the classes are polymorphic because they are using a single interface to use with entities of different types. A function will be able to evaluate these polymorphic methods without knowing which classes are invoked.

Creating Polymorphic Classes

To make use of polymorphism, we’re going to create two distinct classes to use with two distinct objects. Each of these distinct classes need to have an interface that is in common so that they can be used polymorphically, so we will give them methods that are distinct but that have the same name.

We’ll create a Shark class and a Clownfish class, each of which will define methods for swim(), swim_backwards(), and skeleton().

polymorphic_fish.py
class Shark():
    def swim(self):
        print("The shark is swimming.")

    def swim_backwards(self):
        print("The shark cannot swim backwards, but can sink backwards.")

    def skeleton(self):
        print("The shark's skeleton is made of cartilage.")


class Clownfish():
    def swim(self):
        print("The clownfish is swimming.")

    def swim_backwards(self):
        print("The clownfish can swim backwards.")

    def skeleton(self):
        print("The clownfish's skeleton is made of bone.")

In the code above, both the Shark and Clownfish class have three methods with the same name in common. However, each of the functionalities of these methods differ for each class.

Let’s instantiate these classes into two objects:

polymorphic_fish.py
...
sammy = Shark()
sammy.skeleton()

casey = Clownfish()
casey.skeleton()

When we run the program with the python polymorphic_fish.py command, we can see that each object behaves as expected:

Output
The shark's skeleton is made of cartilage.
The clownfish's skeleton is made of bone.

Now that we have two objects that make use of a common interface, we can use the two objects in the same way regardless of their individual types.

Polymorphism with Class Methods

To show how Python can use each of these different class types in the same way, we can first create a for loop that iterates through a tuple of objects. Then we can call the methods without being concerned about which class type each object is. We will only assume that these methods actually exist in each class.

polymorphic_fish.py
...
sammy = Shark()

casey = Clownfish()

for fish in (sammy, casey):
    fish.swim()
    fish.swim_backwards()
    fish.skeleton()

We have two objects, sammy of the Shark class, and casey of the Clownfish class. Our for loop iterates through these objects, calling the swim(), swim_backwards(), and skeleton() methods on each.

When we run the program, the output will be as follows:

Output
The shark is swimming.
The shark cannot swim backwards, but can sink backwards.
The shark's skeleton is made of cartilage.
The clownfish is swimming.
The clownfish can swim backwards.
The clownfish's skeleton is made of bone.

The for loop iterated first through the sammy instantiation of the Shark class, then the casey object of the Clownfish class, so we see the methods related to the Shark class first, then the Clownfish class.

This shows that Python is using these methods in a way without knowing or caring exactly what class type each of these objects is. That is, using these methods in a polymorphic way.

Polymorphism with a Function

We can also create a function that can take any object, allowing for polymorphism.

Let’s create a function called in_the_pacific() which takes in an object we can call fish. Though we are using the name fish, any instantiated object will be able to be called into this function:

polymorphic_fish.py
…
def in_the_pacific(fish):

Next, we’ll give the function something to do that uses the fish object we passed to it. In this case we’ll call the swim() methods, each of which is defined in the two classes Shark and Clownfish:

polymorphic_fish.py
...
def in_the_pacific(fish):
    fish.swim()

Next, we’ll create instantiations of both the Shark and Clownfish classes if we don’t have them already. With those, we can call their action using the same in_the_pacific() function:

polymorphic_fish.py
...
def in_the_pacific(fish):
    fish.swim()

sammy = Shark()

casey = Clownfish()

in_the_pacific(sammy)
in_the_pacific(casey)

When we run the program, the output will be as follows:

Output
The shark is swimming.
The clownfish is swimming.

Even though we passed a random object (fish) into the in_the_pacific() function when defining it, we were still able to use it effectively for instantiations of the Shark and Clownfish classes. The casey object called the swim() method defined in the Clownfish class, and the sammy object called the swim() method defined in the Shark class.

Conclusion

By allowing different objects to leverage functions and methods in similar ways through polymorphism, making use of this Python feature provides greater flexibility and extendability of your object-oriented code.

Annotate

Next Chapter
How To Use the Python Debugger
PreviousNext
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License
Powered by Manifold Scholarship. Learn more at
Opens in new tab or windowmanifoldapp.org