Polymorphism — duck typing, same interface different behavior
2.1.12· Coding › OOP Fundamentals
Polymorphism KYA hai?
Do flavors hain jinhe tumhe apne dimag mein alag rakhna hai:
| Kind | Idea | Python example |
|---|---|---|
| Subtype / inheritance | Ek subclass parent method ko override karta hai | Dog(Animal) speak() ko override karta hai |
| Duck typing | Koi bhi object jo method rakhta ho woh kaam karta hai — koi inheritance ki zaroorat nahi | kuch bhi jisme .speak() ho |
Yeh Python mein kyun kaam karta hai? (First principles)
Toh Python mein polymorphism koi special feature nahi hai — yeh dynamic attribute lookup se naturally nikalta hai. Koi compile-time type contract satisfy karna nahi hai.
Isko kaise use karein — scratch se build karo
Sabse general, type-agnostic version se shuru karo (pure duck typing):
def make_it_speak(thing):
return thing.speak() # hum sirf yeh chahte hain: thing ke paas .speak() hoAb ise bahut saare "ducks" do:
class Dog:
def speak(self): return "Woof"
class Cat:
def speak(self): return "Meow"
class Robot: # Dog/Cat se bilkul related nahi
def speak(self): return "Beep boop"
for t in (Dog(), Cat(), Robot()):
print(make_it_speak(t)) # Woof / Meow / Beep boopInheritance wala flavor (override)
class Animal:
def speak(self):
raise NotImplementedError # base "promise" karta hai interface ka
class Dog(Animal):
def speak(self): return "Woof" # override
class Cat(Animal):
def speak(self): return "Meow" # override
Worked Example 1 — Ek len-jaisa total cost
class Book:
def __init__(self, price): self.price = price
class Cart:
def __init__(self, items): self.items = items
def total(self):
return sum(i.price for i in self.items)Yeh step kyun? total() Book ke liye kaam karta hai, lekin kisi bhi object ke liye jo .price attribute rakhta ho — ek Toy, ek Subscription, etc. Humne ek interface code kiya (has .price), koi type nahi.
Worked Example 2 — Polymorphic area()
import math
class Circle:
def __init__(self, r): self.r = r
def area(self): return math.pi * self.r**2
class Square:
def __init__(self, s): self.s = s
def area(self): return self.s**2
def total_area(shapes):
return sum(s.area() for s in shapes)
total_area([Circle(1), Square(2)]) # π·1² + 2² = π + 4 ≈ 7.1416Yeh step kyun? total_area ek baar likha jaata hai. Same call s.area() circle ke liye run karta hai aur square ke liye — same interface, different behavior. Baad mein Triangle add karo → total_area mein zero changes.
Worked Example 3 — Built-in polymorphism (+)
1 + 2 # 3 (int.__add__)
"a" + "b" # "ab" (str.__add__)
[1] + [2] # [1, 2] (list.__add__)Yeh step kyun? + same operator name hai jo alag-alag type ke liye alag __add__ ko dispatch karta hai. Yahi operator polymorphism hai — Python ka syntax bhi duck-typed hai (yeh bas __add__ call karta hai).
Recall Feynman: 12 saal ke bacche ko samjhao
Socho ek TV remote hai jisme ek bada lal "GO" button hai. Car remote par press karo → car chalta hai. Wohi button drone remote par press karo → drone udta hai. Same button, alag machine, alag result. Tumhe yeh nahi jaanna ki machine andar se kaise kaam karti hai — bas GO press karo aur woh apna kaam karti hai. Code mein, "GO" method name hai jaise speak(), aur machine object hai. Jab tak kisi machine ke paas GO button hai, tumhara remote uske saath kaam karta hai — chahe kal koi brand-new toy kyun na invent ho.
Flashcards
"Polymorphism" ka literal translation kya hai?
Duck typing ko ek line mein define karo.
Kya Python ko polymorphism ke liye inheritance chahiye?
x.foo() call karne par runtime mein kya hota hai?
foo ko type(x).__mro__ ke zariye dhundhta hai; pehla mila woh call karta hai, nahi toh AttributeError raise hota hai.Polymorphism ke liye har jagah isinstance check karna anti-pattern kyun hai?
hasattr capability checks prefer karo.Polymorphism ke do flavors bolo.
+ polymorphism ka example kyun hai?
__add__ ko dispatch karta hai (int add karta hai, str/list concatenate karte hain).Parent method ko override karne aur overwrite karne mein kya fark hai?
EAFP ka matlab kya hai?
total_area(shapes) ek baar likhna baad mein invent hone wali shapes ko kyun support karta hai?
.area() interface par rely karta hai, toh koi bhi future object jo area() rakhta ho bina kisi change ke plug in ho jaata hai.Connections
- Inheritance — overriding and super()
- Abstraction — interfaces and abstract base classes (ABC)
- Dunder methods — __add__, __len__, __str__
- Method Resolution Order (MRO)
- EAFP vs LBYL — Pythonic error handling
- Encapsulation — bundling data and behavior
- Liskov Substitution Principle (SOLID)