جلسه 8چندریختی
تعریف چندریختی
چندریختی یکی از اصول بنیادی برنامهنویسی شیءگرا (OOP) است که به اشیاء اجازه میدهد تا رفتارهای متفاوتی را در پاسخ به یک فراخوانی یکسان از خود نشان دهند. این اصل به کدها انعطافپذیری، قابلیت خوانایی و توسعهپذیری بالایی میبخشد. به عبارت دیگر، چندریختی به شما امکان میدهد تا با استفاده از یک رابط (Interface) مشترک، با انواع مختلفی از اشیاء تعامل داشته باشید، بدون اینکه نیاز باشد از نوع دقیق هر شیء اطلاع داشته باشید.
انواع چندریختی
در برنامهنویسی شیءگرا، چندریختی به دو شکل اصلی پیادهسازی میشود:
- چندریختی در زمان کامپایل (Compile-time Polymorphism / Static Polymorphism):
این نوع چندریختی در زمان کامپایل مشخص میشود و معمولاً از طریق بازنویسی توابع (Function Overloading) و عملگرها (Operator Overloading) پیادهسازی میگردد.
- بازنویسی توابع: به شما اجازه میدهد تا چندین تابع با نام یکسان اما با پارامترهای متفاوت (تعداد، نوع یا ترتیب پارامترها) در یک کلاس داشته باشید. کامپایلر بر اساس آرگومانهای ارسالی، تابع صحیح را فراخوانی میکند.
- بازنویسی عملگرها: به شما امکان میدهد تا معنای عملگرهای استاندارد (مانند
+,-,*,/) را برای انواع دادههای سفارشی خود (کلاسها) بازتعریف کنید.
- چندریختی در زمان اجرا (Run-time Polymorphism / Dynamic Polymorphism):
این نوع چندریختی در زمان اجرای برنامه مشخص میشود و عمدتاً از طریق ارثبری (Inheritance) و بازتعریف توابع مجازی (Virtual Function Overriding) پیادهسازی میگردد.
- ارثبری: یک کلاس (کلاس فرزند) میتواند ویژگیها و متدهای کلاس دیگر (کلاس والد) را به ارث ببرد.
- بازتعریف توابع مجازی: اگر متدی در کلاس والد به صورت
virtualتعریف شده باشد، کلاسهای فرزند میتوانند آن متد را بازتعریف (Override) کنند. زمانی که یک اشارهگر یا ارجاع از نوع کلاس والد به یک شیء از کلاس فرزند اشاره میکند، فراخوانی متد مجازی در زمان اجرا به متد بازتعریف شده در کلاس فرزند هدایت میشود. این مکانیسم، هسته اصلی چندریختی در زمان اجرا است.
اهمیت چندریختی در مهندسی نرمافزار
- کاهش پیچیدگی کد: با استفاده از چندریختی، میتوان کدی نوشت که با انواع مختلف دادهها به صورت یکسان کار کند، که این امر از نوشتن کدهای شرطی تکراری (مانند
if-elseیاswitch-case) جلوگیری میکند. - افزایش قابلیت نگهداری و توسعه: سیستمهایی که از چندریختی استفاده میکنند، آسانتر قابل نگهداری و توسعه هستند. اضافه کردن انواع جدیدی از اشیاء که با رابط مشترک سازگار باشند، بدون نیاز به تغییر کدهای موجود امکانپذیر است.
- بهبود طراحی نرمافزار: چندریختی به طراحان کمک میکند تا مدلهای شیءگرا با ساختار منعطفتر و قویتری ایجاد کنند.
- توسعهپذیری: این اصل امکان افزودن قابلیتهای جدید به سیستم را بدون تأثیر بر بخشهای موجود فراهم میکند.
تمرین پایان فصل
- یک کلاس پایه به نام
Shapeبا یک متد مجازیdraw()تعریف کنید. - دو کلاس مشتق از
Shapeبه نامهایCircleوRectangleایجاد کنید و متدdraw()را در هر کدام به صورت جداگانه پیادهسازی کنید تا شکل مربوطه را ترسیم کند (در حد نمایش یک پیام متنی). - تابعی بنویسید که لیستی از اشارهگرهای
Shapeرا دریافت کند و برای هر شیء در لیست، متدdraw()را فراخوانی کند. - در تابع
main، اشیائی ازCircleوRectangleایجاد کرده و آنها را به لیست اشارهگرهایShapeاضافه کنید، سپس تابع ترسیم را فراخوانی کنید و خروجی را مشاهده کنید. - (اختیاری) مفهوم Operator Overloading را با پیادهسازی عملگر
+برای جمع کردن مختصات دو نقطه در یک کلاسPointنشان دهید.
خلاصه نکات کلیدی
- چندریختی (Polymorphism): توانایی اشیاء در اتخاذ فرمهای متعدد.
- دو نوع اصلی: زمان کامپایل (Static) و زمان اجرا (Dynamic).
- چندریختی زمان کامپایل: شامل Function Overloading و Operator Overloading. در زمان کامپایل مشخص میشود.
- چندریختی زمان اجرا: شامل Inheritance و Virtual Function Overriding. در زمان اجرا مشخص میشود.
- ارثبری و توابع مجازی: کلیدهای اصلی پیادهسازی چندریختی در زمان اجرا.
- مزایا: کاهش پیچیدگی، افزایش قابلیت نگهداری، بهبود طراحی و توسعهپذیری کد.
- کاربرد: امکان رفتار متفاوت اشیاء در پاسخ به یک فراخوانی یکسان از طریق یک رابط مشترک.