ಪಾಲಿಮಾರ್ಫಿಸಮ್ (Polymorphism)
ಪಾಲಿಮಾರ್ಫಿಸಮ್ (Polymorphism) ಎಂಬ ಪದವು ಗ್ರೀಕ್ ಭಾಷೆಯಿಂದ ಬಂದಿದೆ, ಇದರರ್ಥ "ಹಲವು ರೂಪಗಳು" (poly = many, morph = forms). ಆಬ್ಜೆಕ್ಟ್-ಓರಿಯೆಂಟೆಡ್ ಪ್ರೋಗ್ರಾಮಿಂಗ್ನಲ್ಲಿ, ಪಾಲಿಮಾರ್ಫಿಸಮ್ ಎಂದರೆ ಒಂದೇ ಹೆಸರಿನ ಮೆಥಡ್ ಅಥವಾ ಆಪರೇಟರ್ ಅನ್ನು ವಿಭಿನ್ನ ರೀತಿಯಲ್ಲಿ (ವಿಭಿನ್ನ ಕ್ಲಾಸ್ಗಳಲ್ಲಿ) ಬಳಸುವುದು.
ಇದು ಕೋಡ್ ಅನ್ನು ಹೆಚ್ಚು ಸಾಮಾನ್ಯ ಮತ್ತು ಹೊಂದಿಕೊಳ್ಳುವಂತೆ ಮಾಡಲು ಸಹಾಯ ಮಾಡುತ್ತದೆ.
ಪಾಲಿಮಾರ್ಫಿಸಮ್ ಅನ್ನು ಏಕೆ ಬಳಸಬೇಕು?
- ಹೊಂದಿಕೊಳ್ಳುವಿಕೆ (Flexibility): ಒಂದೇ ಫಂಕ್ಷನ್ ಅಥವಾ ಮೆಥಡ್ ವಿಭಿನ್ನ ಡೇಟಾ ಪ್ರಕಾರಗಳು ಅಥವಾ ಆಬ್ಜೆಕ್ಟ್ಗಳೊಂದಿಗೆ ಕೆಲಸ ಮಾಡಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ.
- ಕೋಡ್ ಸರಳತೆ: ಒಂದೇ ಇಂಟರ್ಫೇಸ್ ಬಳಸಿ ವಿಭಿನ್ನ ಆಬ್ಜೆಕ್ಟ್ಗಳನ್ನು ನಿಯಂತ್ರಿಸಬಹುದು.
- ವಿಸ್ತರಣೀಯತೆ (Extensibility): ಹೊಸ ಕ್ಲಾಸ್ಗಳನ್ನು ಸುಲಭವಾಗಿ ಸೇರಿಸಬಹುದು, ಮತ್ತು ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಕೋಡ್ ಬದಲಾಯಿಸದೆ ಅವುಗಳು ಪಾಲಿಮಾರ್ಫಿಕ್ ರಚನೆಯಲ್ಲಿ ಕೆಲಸ ಮಾಡುತ್ತವೆ.
ಪೈಥಾನ್ನಲ್ಲಿ ಪಾಲಿಮಾರ್ಫಿಸಮ್ ಅನ್ನು ಎರಡು ಮುಖ್ಯ ರೀತಿಗಳಲ್ಲಿ ಸಾಧಿಸಬಹುದು: 1. ಡಕ್ ಟೈಪಿಂಗ್ (Duck Typing) 2. ಮೆಥಡ್ ಓವರ್ರೈಡಿಂಗ್ (Method Overriding)
1. ಡಕ್ ಟೈಪಿಂಗ್ (Duck Typing)
"If it walks like a duck and it quacks like a duck, then it must be a duck." - ಈ ತತ್ವದ ಮೇಲೆ ಡಕ್ ಟೈಪಿಂಗ್ ಕೆಲಸ ಮಾಡುತ್ತದೆ.
ಇದರರ್ಥ, ಒಂದು ಆಬ್ಜೆಕ್ಟ್ನ ಪ್ರಕಾರಕ್ಕಿಂತ (type) ಅದರ ಗುಣಲಕ್ಷಣಗಳು ಮತ್ತು ವರ್ತನೆಗಳು (attributes and methods) ಮುಖ್ಯ. ಒಂದು ಫಂಕ್ಷನ್ಗೆ ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ಪಾಸ್ ಮಾಡಿದಾಗ, ಆ ಫಂಕ್ಷನ್ ಆಬ್ಜೆಕ್ಟ್ನ ನಿರ್ದಿಷ್ಟ ಪ್ರಕಾರವನ್ನು ಪರಿಶೀಲಿಸುವುದಿಲ್ಲ. ಬದಲಾಗಿ, ಅದು ಅಗತ್ಯವಿರುವ ಮೆಥಡ್ ಅಥವಾ ಅಟ್ರಿಬ್ಯೂಟ್ ಅನ್ನು ಹೊಂದಿದೆಯೇ ಎಂದು ಮಾತ್ರ ನೋಡುತ್ತದೆ.
ಉದಾಹರಣೆ:
class Dog:
def speak(self):
return "ಬೊಗಳುತ್ತದೆ!"
class Cat:
def speak(self):
return "ಮ്യാว್ ಮ್ಯಾว್!"
class Duck:
def speak(self):
return "ಕ್ವಾಕ್ ಕ್ವಾಕ್!"
# ಈ ಫಂಕ್ಷನ್ ಯಾವುದೇ ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ಸ್ವೀಕರಿಸುತ್ತದೆ,
# ಆದರೆ ಅದಕ್ಕೆ 'speak' ಮೆಥಡ್ ಇರಬೇಕು.
def make_sound(animal):
print(animal.speak())
# ಆಬ್ಜೆಕ್ಟ್ಗಳನ್ನು ರಚಿಸುವುದು
dog = Dog()
cat = Cat()
duck = Duck()
# ಒಂದೇ ಫಂಕ್ಷನ್ ಅನ್ನು ವಿಭಿನ್ನ ಆಬ್ಜೆಕ್ಟ್ಗಳೊಂದಿಗೆ ಬಳಸುವುದು
make_sound(dog)
make_sound(cat)
make_sound(duck)
make_sound ಫಂಕ್ಷನ್ಗೆ Dog, Cat, ಅಥವಾ Duck ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ಪಾಸ್ ಮಾಡಿದರೂ, ಅದು ಸರಿಯಾಗಿ ಕೆಲಸ ಮಾಡುತ್ತದೆ. ಏಕೆಂದರೆ, ಎಲ್ಲಾ ಕ್ಲಾಸ್ಗಳೂ speak ಎಂಬ ಮೆಥಡ್ ಅನ್ನು ಹೊಂದಿವೆ.
2. ಮೆಥಡ್ ಓವರ್ರೈಡಿಂಗ್ (Method Overriding)
ಇನ್ಹೆರಿಟೆನ್ಸ್ನಲ್ಲಿ, ಚೈಲ್ಡ್ ಕ್ಲಾಸ್ ಪೇರೆಂಟ್ ಕ್ಲಾಸ್ನ ಮೆಥಡ್ ಅನ್ನು ತನ್ನದೇ ಆದ ರೀತಿಯಲ್ಲಿ ಪುನಃ ವ್ಯಾಖ್ಯಾನಿಸಿದರೆ, ಅದನ್ನು ಮೆಥಡ್ ಓವರ್ರೈಡಿಂಗ್ ಎನ್ನುತ್ತಾರೆ.
ಇದು ಪಾಲಿಮಾರ್ಫಿಸಮ್ನ ಒಂದು ಶಕ್ತಿಯುತ ರೂಪವಾಗಿದೆ.
ಉದಾಹರಣೆ:
# ಪೇರೆಂಟ್ ಕ್ಲಾಸ್
class Vehicle:
def start(self):
print("ವಾಹನ ಚಾಲೂ ಆಯಿತು.")
# ಚೈಲ್ಡ್ ಕ್ಲಾಸ್
class Car(Vehicle):
# ಪೇರೆಂಟ್ ಕ್ಲಾಸ್ನ 'start' ಮೆಥಡ್ ಅನ್ನು ಓವರ್ರೈಡ್ ಮಾಡುವುದು
def start(self):
print("ಕಾರು ಕೀ ಬಳಸಿ ಚಾಲೂ ಆಯಿತು.")
# ಮತ್ತೊಂದು ಚೈಲ್ಡ್ ಕ್ಲಾಸ್
class ElectricBike(Vehicle):
# ಪೇರೆಂಟ್ ಕ್ಲಾಸ್ನ 'start' ಮೆಥಡ್ ಅನ್ನು ಓವರ್ರೈಡ್ ಮಾಡುವುದು
def start(self):
print("ಎಲೆಕ್ಟ್ರಿಕ್ ಬೈಕ್ ಬಟನ್ ಒತ್ತಿ ಚಾಲೂ ಆಯಿತು.")
# ಆಬ್ಜೆಕ್ಟ್ಗಳನ್ನು ರಚಿಸುವುದು
vehicle = Vehicle()
car = Car()
bike = ElectricBike()
# ಒಂದೇ ಹೆಸರಿನ ಮೆಥಡ್, ಆದರೆ ವಿಭಿನ್ನ ವರ್ತನೆ
vehicle.start()
car.start()
bike.start()
Car ಮತ್ತು ElectricBike ಕ್ಲಾಸ್ಗಳು Vehicle ಕ್ಲಾಸ್ನ start ಮೆಥಡ್ ಅನ್ನು ತಮ್ಮದೇ ಆದ ರೀತಿಯಲ್ಲಿ ಕಾರ್ಯಗತಗೊಳಿಸಿವೆ.
ಆಪರೇಟರ್ ಓವರ್ಲೋಡಿಂಗ್ (Operator Overloading)
ಪಾಲಿಮಾರ್ಫಿಸಮ್ನ ಮತ್ತೊಂದು ರೂಪವೆಂದರೆ ಆಪರೇಟರ್ ಓವರ್ಲೋಡಿಂಗ್. ಪೈಥಾನ್ನಲ್ಲಿ, +, -, * ಮುಂತಾದ ಆಪರೇಟರ್ಗಳು ವಿಭಿನ್ನ ಡೇಟಾ ಪ್ರಕಾರಗಳೊಂದಿಗೆ ವಿಭಿನ್ನವಾಗಿ ವರ್ತಿಸುತ್ತವೆ.
5 + 3ಇಲ್ಲಿ+ಸಂಖ್ಯೆಗಳನ್ನು ಕೂಡಿಸುತ್ತದೆ (ಸಂಕಲನ)."ಹಲೋ" + " ವರ್ಲ್ಡ್"ಇಲ್ಲಿ+ಸ್ಟ್ರಿಂಗ್ಗಳನ್ನು ಜೋಡಿಸುತ್ತದೆ (concatenation).
ನಾವು ನಮ್ಮದೇ ಕ್ಲಾಸ್ಗಳಲ್ಲಿ ಈ ಆಪರೇಟರ್ಗಳ ವರ್ತನೆಯನ್ನು ವಿಶೇಷ ಮೆಥಡ್ಗಳನ್ನು (magic methods) ಬಳಸಿ ವ್ಯಾಖ್ಯಾನಿಸಬಹುದು.
ಉದಾಹರಣೆ:
ಎರಡು Vector ಆಬ್ಜೆಕ್ಟ್ಗಳನ್ನು + ಆಪರೇಟರ್ ಬಳಸಿ ಕೂಡಿಸುವಂತೆ ಮಾಡೋಣ.
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
# '+' ಆಪರೇಟರ್ ಅನ್ನು ಓವರ್ಲೋಡ್ ಮಾಡಲು __add__ ಮೆಥಡ್
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __str__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(2, 4)
v2 = Vector(5, -2)
# __add__ ಮೆಥಡ್ ಇಲ್ಲಿ ಕರೆಯಲ್ಪಡುತ್ತದೆ
v3 = v1 + v2
print(v1)
print(v2)
print(v3)
v1 + v2 ಎಂದು ಬರೆದಾಗ, ಪೈಥಾನ್ ಆಂತರಿಕವಾಗಿ v1.__add__(v2) ಅನ್ನು ಕರೆಯುತ್ತದೆ. ಹೀಗೆ, ನಾವು + ಆಪರೇಟರ್ಗೆ ಹೊಸ ಅರ್ಥವನ್ನು ನೀಡಿದ್ದೇವೆ.