In previous lessons, you learnt Inheritance, and Encapsulation.
In this lesson, you will learn about,
the third pillar of Object Oriented Programming, Polymorphism.
What is Polymorphism ?
Well Polymorphism means, object in many forms.
In other words the object’s ability to assume various forms.
In Python, Polymorphism is having, same interface(i.e method)
between two classes.
It’s that simple.
In Python, Polymorphism is achieved through,
method overriding and duck typing.
Virtual functions
By nature methods in Python are virtual,
that is, you can override methods.
What is overriding ?
A method in a parent class, is having different
definition in child class.
It’s just enough, to have same method name
in both Parent and Child classes.
Overriding is one type Polymorphism.
class Parent(object): def a_method(self): print("I'm a parent method") def another_method(self): print("I'm parent another method") class Child(Parent): def a_method(self): print("I'm a child method") # Creating a Parent object p1 = Parent() p1.a_method() p1.another_method() output: I'm a parent method I'm parent another method #creating a Child object c1 = Child() c1.a_method() c1.another_method() output: I'm a child method I'm parent another method
Notice in above example, we have overridden a_method(), in Child() class.
And another_method() is inherited from Parent without modification.
What is ducktyping ?
Duck typing is reading attributes of objects,
without actually bothering about the type of the object.
In the above example we have common method a_method()
Which can be accessed without checking type object.
For example in our code, we want to access the a_method()
of Parent and Child class objects.
Let’s say we have four objects like below.
and we will call common method a_method() without
worrying about its class or type.
# creating Parent objects p1 = Parent() p2 = Parent() # creating child objects c1 = Child() c2 = Child() # accessing a_method() objs = (p1,c1,p2,c2) for obj in objs: obj.a_method() output: I'm a parent method I'm a child method I'm a parent method I'm a child method
Lets look at another example where un related
classes implement same interface.
class Bird(object): def fly(self): print("Bird is flying") class Airplane(object): def fly(self): print("Airplane is flying") class Kite(object): def fly(self): print("Kite is flying") b1 = Bird() a1 = Airplane() c1 = Kite() flying_object = (a1,b1,c1) for obj in flying_object: obj.fly() output: Airplane is flying Bird is flying Kite is flying
Now flying_object is collection of different objects, here we are
accessing obj property fly() without checking whether
type of the object. It’s believed, that all the three classes
Bird, Airplane, and Kite respect interface contract, that is
to implement fly() method.
More about duck typing
Duck typing is named after The duck test attributed to
James William Riley, The American poet.
“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”
– James William Riley
If two related classes implement common interface(method),
then interface can be accessed without checking the object type.
As longs as the classes respects the contract interface,
If we have to check type of the object before
dealing with object, it is un Pythonic.
Polymorphism in Built in types
You will seen Polymorphism every where in Python.
In Python there are many built in functions
which demonstrate Polymorphism.
len() – irrespective of type it returns, the number of objects in collection
internally its __len__(self,object):
len("i'm a string") len([0,1,2,3,4,5,6]) len({'one':1, 'two':2}) etc...
Here each String, List, Dict classes have,
common __len__() method. That’s is respecting
the interface contract.
You can verify this, using dir() on object.
dir("i'm a string") dir([0,1,2,3,4,5,6]) dir({'one':1, 'two':2})
you will see the __len__() is common method,
implemented in all three.
Like wise you have add() method for string and lists.
add() __addd__(self,object)
add() is method invoked when you use ‘+’ plus operator on objects.
"this " + "that" or [1,2,3] + [4,5,6]
Another popular operator ‘in’ is also
implemented as method __contains__()
in strings, lists, tuple, dict,sets etc…