چندریختی چیست؟
چندریختی (Polymorphism) در برنامهنویسی به توانایی یک شیء برای اتخاذ شکلهای متفاوت گفته میشود. به عبارت دیگر، چند ریختی به این معنی است که یک متد یا عملگر میتواند رفتارهای متفاوتی را بر اساس نوع ورودیهای خود اجرا کند. در پایتون، چند ریختی به روشهای زیر در دسترس قرار میگیرد:
1. متدهای چند ریختی: یک متد میتواند رفتارهای متفاوتی را بر اساس نوع ورودیهایش اجرا کند. این قابلیت به برنامهنویس این امکان را میدهد تا رابط عمومی را برای اشیاء مختلف ایجاد کند.
2. ارثبری: کلاسهای فرزند میتوانند متدهای موجود در کلاس پدر را بازنویسی کنند تا رفتار متفاوتی از آنها ارائه دهند.
3. اشیاء چند ریختی: یک شیء میتواند به عنوان نمونهای از چندین کلاس مختلف عمل کند و این امکان استفاده از رفتارهای مختلف بر اساس نیاز را فراهم میکند.
چند ریختی به برنامهنویسان اجازه میدهد تا کد انعطافپذیر و قابل استفاده مجدد بنویسند که به راحتی با تغییرات سازگار است. این ویژگی یکی از اصول طراحی شیءگرا است که به ایجاد کدهای مدولار و قابل توسعه کمک میکند.
چند ریختی در تابع توکار len
در پایتون، تابع len یک مثال کلاسیک از چند ریختی است. تابع len میتواند با انواع مختلف دادهها کار کند و همواره طول یا اندازه آن را برمیگرداند. برای مثال:
print(len([1, 2, 3]))
# Output: 3
print(len("hello"))
# Output: 5
print(len({1, 2, 3}))
# Output: 3
در این مثال، تابع len میتواند با لیست، رشته و مجموعه کار کند و در هر مورد طول یا اندازه آنها را برمیگرداند. این چند ریختی به دلیل اینکه تابع len میتواند با انواع مختلف دادهها کار کند، به برنامهنویسان این امکان را میدهد که از یک رابط یکسان برای دسترسی به طول یا اندازه انواع مختلف دادهها استفاده کنند. این به انسجام و یکپارچگی کد کمک میکند. چند ریختی در تابع len نمونهای از چند ریختی در پایتون است که به عنوان یک ویژگی قدرتمند زبان پایتون شناخته میشود.
چند ریختی با وراثت
در پایتون، چند ریختی با استفاده از وراثت مفهوم بسیار قدرتمندی است. این امکان را به برنامهنویسان میدهد تا رفتار متنوعی را در برنامههای خود پیادهسازی کنند. چند ریختی با وراثت به این صورت عمل میکند که یک کلاس پایه (parent class) تعریف میشود که متدهای پایه را فراهم میکند. سپس کلاسهای فرعی (child classes) از این کلاس پایه ارث میبرند و میتوانند متدهای پایه را بازنویسی (overriding) کنند تا رفتار متنوعی را پیادهسازی نمایند. به عنوان مثال، فرض کنید که داریم یک کلاس پایه به نام Animal که متد make_sound را تعریف کرده است. سپس، کلاسهای فرعی Dog و Cat از این کلاس پایه Animal ارث میبرند و متد make_sound() را بازنویسی میکنند تا صدای مخصوص هر حیوان را بازگردانند.
class Animal:
def make_sound(self):
print("The animal makes a sound")
class Dog(Animal):
def make_sound(self):
print("Woof!")
class Cat(Animal):
def make_sound(self):
print("Meow!")
# استفاده از چند ریختی
animals = [Dog(), Cat(), Animal()]
for animal in animals:
animal.make_sound()
در این مثال، هر سه شیء از کلاسهای Dog، Cat و Animal همان متد make_sound را فراخوانی میکنند، اما خروجی متفاوت خواهد بود. این چند ریختی به برنامهنویسان امکان میدهد تا رفتار متنوع را با استفاده از یک رابط یکسان پیادهسازی کنند. چند ریختی در پایتون به طور گسترده در طراحی الگوهای برنامهنویسی شیگرا و همچنین در کتابخانههای استاندارد پایتون استفاده میشود.
مزایای قابلیت بازنویسی متد
بازنویسی متدها (method overriding) در چند ریختی پایتون دارای چند مزیت مهم است:
1. انعطافپذیری و قابلیت سفارشیسازی
از طریق بازنویسی متدها، کلاسهای فرعی میتوانند رفتار پایهای را تغییر دهند و آن را به نیازهای خاص خود سفارشیسازی کنند. این امکان به برنامهنویسان اجازه میدهد تا سیستمهای قابل گسترش و انعطافپذیر طراحی کنند.
2. کد قابل خواندن و درک
از طریق بازنویسی متدها، کد برنامه از نظر معنایی و موضوعی واضحتر و قابل درکتر میشود. این امر به ویژه در برنامههای بزرگ و پیچیده بسیار مفید است و خوانایی و نگهداری کد را بهبود میبخشد.
3. کاهش تکرار کد
بازنویسی متدها امکان استفاده مجدد از کد را فراهم میکند. به جای تکرار کدهای مشابه در هر کلاس فرعی، میتوان متدها را در کلاس پایه تعریف کرد و در کلاسهای فرعی بازنویسی نمود. این قابلیت باعث کاهش کد تکراری و افزایش قابلیت نگهداری کد میشود.
4. پلیمورفیسم
بازنویسی متدها امکان پلیمورفیسم را فراهم میکند. یک شیء میتواند به عنوان یک نمونه از کلاس پایه یا کلاس فرعی عمل کند و متد مربوطه را به شکل متناسب با خود اجرا کند. این ویژگی به برنامهنویسان امکان میدهد تا با یک رابط یکپارچه، رفتارهای متنوعی را پیادهسازی کنند.
در مجموع، بازنویسی متدها یکی از قدرتمندترین ویژگیهای چند ریختی در پایتون است که به ایجاد کدهای انعطافپذیر، قابل خواندن و قابل نگهداری کمک میکند.
مثال به همراه کد برای بازنویسی متد
برای درک بهتر موضوع اجازه دهید به ذکر مثالی بپردازیم. در این مثال، ما یک کلاس Animal با متد make_sound داریم. سپس، دو کلاس فرعی Dog و Cat از کلاس Animal ایجاد میکنیم و متد make_sound را در هر یک از این کلاسها بازنویسی میکنیم:
class Animal:
def __init__(self, name):
self.name = name
def make_sound(self):
print("The animal makes a sound.")
class Dog(Animal):
def make_sound(self):
print("The dog barks.")
class Cat(Animal):
def make_sound(self):
print("The cat meows.")
# تست کد
dog = Dog("Buddy")
cat = Cat("Whiskers")
dog.make_sound() # Output: The dog barks.
cat.make_sound() # Output: The cat meows.
در قطعه کد بالا، کلاس Animal دارای متد make_sound است که یک پیام عمومی چاپ میکند. کلاسهای فرعی Dog و Cat از کلاس Animal ارثبری میکنند و متد make_sound را بازنویسی میکنند تا رفتار متناسب با هر نوع حیوان را نشان دهند. هنگامی که شیءهای dog و cat ایجاد میشوند و متد make_sound بر روی آنها فراخوانی میشود، خروجی مربوط به هر نوع حیوان چاپ میشود. این مثال نشان میدهد که چگونه بازنویسی متدها به ما امکان میدهد تا رفتار پایه را تغییر دهیم و کد انعطافپذیر و قابل توسعهتری ایجاد کنیم.
چند ریختی در متدهای کلاسی
در زبانهای برنامهنویسی شیگرا، چندریختی (polymorphism) این امکان را فراهم میکند که پیادهسازیهای متفاوت از یک متد در کلاسهای مختلف داشته باشیم. رویکرد فوق به برنامهنویس این امکان را میدهد تا رفتار یک شی را به صورت پویا تغییر دهد بدون اینکه نیاز باشد کد را به طور مستقیم تغییر دهد. در پایتون، چندریختی در متدهای کلاسی به چندین شکل امکان پذیر است:
1. Overriding (بازنویسی متد):
در این حالت، متد با همان نام در کلاس فرعی تعریف می شود که رفتار آن متفاوت از کلاس پایه است.
class Animal:
def make_sound(self):
print("The animal makes a sound.")
class Dog(Animal):
def make_sound(self):
print("The dog barks.")
dog = Dog()
dog.make_sound() # Output: The dog barks.
2. Operator Overloading:
این قابلیت اجازه میدهد رفتار عملگرهای استاندارد مانند +, -, , / را برای اشیای کلاس خود تعریف کنید.
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
p1 = Point(1, 2)
p2 = Point(3, 4)
p3 = p1 + p2
print(p3.x, p3.y) # Output: 4 6
3. Method Overloading:
در این حالت، یک متد با تعداد پارامترهای متفاوت تعریف میشود. پایتون به طور مستقیم پشتیبانی از متد overloading را ندارد، اما میتوان از روشهای جایگزین مانند استفاده از args و kwargs استفاده کرد.
class Calculator:
def add(self, a, b):
return a + b
def add(self, a, b, c):
return a + b + c
در مجموع، چندریختی به ما امکان میدهد تا رفتار اشیای مختلف را به صورت یکنواخت مدیریت کنیم و کد انعطافپذیرتر و قابل توسعهتری داشته باشیم.
چند ریختی در متدهای توکار
چندریختی (polymorphism) در متدهای توکار (built-in methods) یک مفهوم مهم در برنامهنویسی شیگرا است که این امکان را به برنامهنویسان میدهد که رفتار پیشفرض متدهای توکار را بر اساس نیازهای خاص خود تغییر دهند. از مثالهای چندریختی در متدهای توکار در زبان پایتون به موارد زیر باید اشاره کرد:
1. __len__: این متد توکار اندازه یک شی را نشان میدهد. میتوان این متد را در کلاس overriding کرد تا رفتار دلخواه را ارائه دهد.
2. __str__ و __repr__: این متدها برای تعریف چگونگی نمایش اشیا به عنوان رشته استفاده میشوند. با overriding آنها میتوان تعیین کرد که شی چگونه نمایش داده شود.
3. متدهای عملگرها مانند __add__, __sub__, __mul__ و غیره: این متدها برای تعریف رفتار عملگرهای ریاضی روی اشیا استفاده میشوند. با overriding میتوان رفتار دلخواه را برای عملگرها تعریف کرد.
چندریختی در متدهای توکار به برنامهنویسان این امکان را میدهد تا رفتار پیشفرض این متدها را تغییر داده و آنها را متناسب با نیاز خود تنظیم کنند. این ویژگی به انعطافپذیری و قابلیت توسعه کدها کمک میکند.
اکنون برای درک بهتر موضوع اجازه دهید به یک مثال عملی در این زمینه اشاره داشته باشیم. در این مثال، فرض کنید که میخواهیم یک کلاس برای حیوانات ایجاد کنیم. هر حیوان میتواند صدایی داشته باشد که متناسب با نوع آن است. برای این منظور، میتوانیم متد __str__ را در کلاس خودمان overriding کنیم تا رفتار پیشفرض این متد را تغییر دهیم.
class Animal:
def __init__(self, name):
self.name = name
def __str__(self):
return f"{self.name} says {self.make_sound()}"
def make_sound(self):
# رفتار پیش فرض
return "..."
class Dog(Animal):
def make_sound(self):
return "Woof!"
class Cat(Animal):
def make_sound(self):
return "Meow!"
# استفاده از کلاس ها
dog = Dog("Buddy")
cat = Cat("Whiskers")
print(dog) # Output: Buddy says Woof!
print(cat) # Output: Whiskers says Meow!
در قطعه کد بالا، کلاس Animal دارای متد __str__ است که رفتار پیش فرض آن برگرداندن یک رشته با استفاده از متد make_sound است. کلاس Dog و Cat از Animal ارثبری میکنند و متد make_sound را overriding میکنند تا صدای مخصوص هر حیوان را برگردانند. هنگامی که اشیاء dog و cat ایجاد و چاپ می شوند، متد __str__ متناسب با نوع هر حیوان اجرا میشود و صدای مخصوص آن را نمایش میدهد. در قطعه کد بالا، چندریختی را به بهترین شکل به تصویر کشیدیم و نشان دادیم که متد __str__ به طور متفاوت برای هر کلاس Dog و Cat اجرا میشود، در حالی که هر دو از کلاس Animal ارثبری میکنند. این ویژگی به انعطافپذیری و قابلیت توسعه کد کمک میکند.
انواع روشهای پیادهسازی چند ریختی در پایتون
در پایتون، روشهای مختلفی برای پیادهسازی چند ریختی وجود دارد که به شرح زیر است:
1. Overriding متدها: رایجترین روش پیادهسازی چند ریختی است. زیرکلاسها میتوانند متدهای پایه خود را overriding کنند و رفتار متفاوتی را فراهم کنند.
2. استفاده از چندین متد با همان نام: پایتون اجازه میدهد تا چند متد با نام یکسان در یک کلاس داشته باشیم. هنگام فراخوانی متد، پایتون متد مناسب را براساس تعداد و نوع پارامترهای ورودی انتخاب میکند. این روش را "overloading" متد مینامند.
3. استفاده از توابع callback: در این روش، کلاس پایه یک متد یا تابع callback را تعریف میکند. زیرکلاسها میتوانند تابع callback را overriding کنند تا رفتار متفاوتی را پیاده سازی کنند. این روش به انعطافپذیری و قابلیت تکرار کد کمک میکند.
4. استفاده از طراحی الگو (Design Patterns): الگوهای طراحی مانند "Strategy"، "Template Method" و "Visitor" میتوانند برای پیادهسازی چند ریختی استفاده شوند. این الگوها به انعطافپذیری بیشتر و قابلیت توسعه کد کمک میکنند.
5. استفاده از چندین پایه (Multiple Inheritance): پایتون اجازه میدهد تا از چند کلاس پایه ارثبری کنیم. این قابلیت به ما کمک میکند تا رفتارهای متفاوتی را در زیرکلاس ها پیاده سازی کنیم، اما استفاده از چند ارثبری ممکن است باعث ایجاد مشکلاتی شود.
در مجموع، هر یک از این روشها در شرایط خاصی مناسب هستند و بسته به نیاز پروژه، میتوان از آنها استفاده کرد تا چند ریختی را پیادهسازی کرد.
Duck Typing در پایتون چیست؟
Duck Typing در پایتون یک مفهوم قدرتمند است که به چند ریختی کمک میکند. در Duck Typing، پایتون به جای چک کردن نوع یک شی، به بررسی رفتار آن میپردازیم. اگر یک شی دارای متدها و خصوصیات مورد نیاز باشد، پایتون آن را به عنوان یک نوع مشخص در نظر میگیرد، بدون نیاز به تعریف صریح آن نوع. این قابلیت یکسری مزایای کلیدی در اختیار ما قرار میدهد که انعطافپذیری، سادگی و قابلیت توسعه از مهمترین آنها است.
ماهنامه شبکه را از کجا تهیه کنیم؟
ماهنامه شبکه را میتوانید از کتابخانههای عمومی سراسر کشور و نیز از دکههای روزنامهفروشی تهیه نمائید.
ثبت اشتراک نسخه کاغذی ماهنامه شبکه
ثبت اشتراک نسخه آنلاین
کتاب الکترونیک +Network راهنمای شبکهها
- برای دانلود تنها کتاب کامل ترجمه فارسی +Network اینجا کلیک کنید.
کتاب الکترونیک دوره مقدماتی آموزش پایتون
- اگر قصد یادگیری برنامهنویسی را دارید ولی هیچ پیشزمینهای ندارید اینجا کلیک کنید.
نظر شما چیست؟