PDA

View Full Version : اصول پلی مورفیسم



marzban
سه شنبه 09 مرداد 1386, 22:32 عصر
با سلام
تو بحث C#.net بحث جالبی بنام پلی مورفیسم رو دیدم
اگه ممکنه یک توضیح بیشتر همراه با کد بدین تا با این موضوع جالب بیشتر آشنا بشیم
با تشکر مرزبان

mahdi_negahi
سه شنبه 09 مرداد 1386, 23:18 عصر
پولیمورفیسم یا چند رختی به عقیده من کار با یک سلسله مراتب از آبجکتها را ساده میکند که ما میتوانیم با حداقل کد نویسی تمام سلسله مراتب را ساپورت کنیم

چند اصطلاح :

upcast:یک شیئ از کلاس بچه به کلاس پدر تبدیل شود ( مثلا گربه به پستانداران تبدیل شود ) این تغییر یک سری از جزئیات را برای ما ناپدید میکند
این توضیح را بدهم که جزئیات نابود نمیشوند بلکه مخفی میشوند مثل اینکه شما با یک دست جلوی یک چشم خود را بگیرید

downcast:عکس بالا

توجه داشته باشید که شما نمیتوانید یک سگ را به پستاندارد upcast کنید و بعد به گربه downcast کنید توجه شود که برای جلوگیری از این خطاها از کلمات کلیدی is و as استفاده کنید

مثال کاربردی :

کلاس پدر employee : یک سری اطلاعات کلی را از کارمندان نگه میدارد ( خیلی کلی) یک کلی نگری محض و یک تابع برای محاسبه حقوق

کلاس فرزند یک DayEmployee : نشان دهنده کارمند رسمی با یک سری خواص بیشتر نسبت به پدر ویک تابع همنام برای محاسبه حقوق ( همنام با تابع کلاس employee)

کلاس فرزند دوم hourEmployee : نشان دهنده کارمند ساعتی ( خواص دیگر شبیه بالا است)

خوب با سلسله مراتب را داریم ولی چند ریختی نداریم
فکر میکنید برای محاسبه حقوق هر کارمند باید چیکار کنیم ؟ به پایین نگاه نکن یک ذره تامل بهت کمک مبکند .



خوب اگر بخوای دو فرم جدا بذاری که راحت از چند ریختی جداست ... و فرمات کار میکنه ولی تو دوبار کد نوشتی

اما چند ریختی : یک کلاس بساز به نام accounting و درون این کلاس تابع بنویس که تابع محاسبه حقوق بابا (employee) را صدا میکند و پارمتر ورودی آن یک ابجک ار employee ( یعنی بابا جونه)
تا اینجا درست ...... یک ذره صغیر به نظر میاد .. حالا در فرم محاسبه حقوق کد زیر را مینویسی


Accounting acc = new Accounting()
Employee emp;
hourEmployee he = new hourEmployee();
DayEmployee dy = new DayEmployee();
emp = (employee)he;// میتوانی dy هم upcast کنی
acc.CalcEmployeepayment(emp);



public class Accounting
{
public int CalcEmployeepayment(Employee em)
{
int payment = em.calcPayment() // همان تابه همنام توی تام سلسله مراتب
}


در ضمن اینم بگم که حتی کد
emp = (employee)he;// میتوانی dy هم upcast کنی
نمیخواد بنویسی میتوانی مستقیما he یا dy را به تابع CalcEmployeepayment بفرستی جون خودش upcast میشود

تمام تو برای 1000 نوع کارمند فقط با یک فرم حقوق محاسبه کردی

اینم بگم مفاهیم OOP یک اصل مهم برای طراحی خوب است اگر تو در هنگام طراحی این سلسله مراتب را ببینی در هنگام پیادهسازی کارت اسونتره
در ضمن اگر کسی هم نظری داره بگه که استفاده کنیم

mahdi_negahi
چهارشنبه 10 مرداد 1386, 20:37 عصر
دوستان دیگر درباره این مبحث مهم هیچ نظری ندارند

Sajjad1364
پنج شنبه 11 مرداد 1386, 14:11 عصر
با سلام
اتفاقا این بحث,داغ ترین وجذاب ترین بحث در سی شارپ می باشد.
مثال آقا مهدی خیلی خوب بود .خواستم در مورد این مثال توضیحاتی بدم.فرض کنیم رییس این کارخانه دو حقوق دارد.یکی حقوق کارمندی خودش ودیگری حقوق سمت رییس.

متد محاسبه حقوق بصورت مجازی در کلاس والد Employee تعریف می شود و دربقیه کلاس ها هم این متد برای هر نوع کارمند جداگانه و با روش دیگری محاسبه میشود.سلسه مراتب
این کلاس ها به اینصورت هست.


class Employee
{
public virtual long CalcPayment()
{محاسبه حقوق}
}
class DayEmployee:Employee
{
public override long CalcPayment()
{
base.CalcPayment();
}
محاسبه حقوق
}
class Manager : DayEmployee
{
public override long CalcPayment()
{
base.CalcPayment();
}
محاسبه حقوق
}

اگر بخواهیم حقوق Manager رو محاسبه کنیم باید یه شئ از این کلاس بسازیم و متد
CalcPayment رو صدا بزنیم.در این صورت شئ Manager باید برای محاسبه حقوق خودش متد CalcPayment از کلاس DayEmployee رو هم صدا بزنه چون یه مدیر بهر حال یه کارمندم هست.این راه حل فقط تا زمانی کار می کند که ما ترتیب وراثت رو بهم نزنیم.یعنی اگر بین کلاس DayEmployee و کلاس Manger یه کلاس دیگه ایجاد کنیم ,این روش محاسبه حقوق کار آمد نمیباشد.برای حل این مشکل میتوانیم سلسله مراتب وراثتی بالا رو اینطور تغییر بدیم.


class Employee
{
public virtual long CalcPayment()
{محاسبه حقوق}
}
class DayEmployee:Employee
{
public override long CalcPayment()
{محاسبه حقوق}
}
class Manager : DayEmployee
{
public new virtual long CalcPayment()
{محاسبه حقوق}
}


حالا اگه در تابع اصلی اینطور بنویسیم حقوق مدیر بدرستی محاسبه میشود.


DayEmployee d = new DayEmployee();
Manager m = new Manager();
long all = m.CalcPayment() + d.CalcPayment();

اگر بجای متد محاسبه حقوق درشکل دوم , متد محاسبه حقوق در شکل اول رو می نوشتیم
خطوط اول و سوم از قطعه کد بالا متد CalcPayment از کلاس Manager رو فراخوانی میکرد.(در صورتیکه این کد برای فرم اول نوشته میشد.)و حقوق به اشتباه دو بار محاسبه میشد.
سی شارپ در برخورد با متدهای مجازی و تحریف شده اینطور عمل میکنه:
همیشه آخرین پیاده سازی از متد موجود در کلاس پایه فراخوانی میشود.در این فراخوانی ملاک,شئ پایه در سمت چپ مساوی است و شئ سمت راست تاثیری در فراخوانی ندارد.
با استفاده از این قاعده کلی به بررسی قطعه کد بالا می پردازیم.
1-کلاس پایه در این خط کلاس DayEmployee میباشد.پس آخرین پیاده سازی که مد نظر است متد CalcPayment از کلاس DayEmployee میباشد.

2-کلاس پایه در این خط کلاسManager میباشد.پس آخرین پیاده سازی که مد نظر است متد CalcPayment از کلاس Manager میباشد.
با توجه به این قاعده قطعه کدهای زیر نتایج یکسانی را بدست میدهند(حقوق, صحیح محاسبه میشود ).


Employee d = new DayEmployee();
Manager m = new Manager();
long all = m.CalcPayment() + d.CalcPayment();

و


Employee d = new Manager();
Manager m = new Manager();
long all = m.CalcPayment() + d.CalcPayment();

و


DayEmployee d = new Manager();
Manager m = new Manager();
long all = m.CalcPayment() + d.CalcPayment();

این انعطاف پذیری ها در فراخوانی متدهای مجازی نشانه پلی مورفیسم موفق در سی شارپ می باشد.

اَرژنگ
پنج شنبه 11 مرداد 1386, 17:26 عصر
(سو)استفاده زیاد از ارث بری هم مشکلات دیگری وارد میکند، از یک لحاظ پلی مرفیزم مانند آجر است.
اینکه هر آجر درست گذاشته بشه کافی نیست، لازم است که اصول مهندسی و آرکیتکتی هم رعایت بشه.
در برنامه نویسی دیزاین پترنها اصول استفاده از پلی مرفیزم را دیکته میکنند، و بدانه استفاده از دیزاین پترنها پلی‌مرفیزم به تنهایی کافی نیست.

11111010
جمعه 22 فروردین 1399, 13:21 عصر
سلام وقتتون بخیر شما این سوال میشه کمک کنید انجامش بدم !
با استفاده از پلی مورفیسم برنامه بنویسید که در کلاس پایه human نام و نام خانوادگی و حقوق دریافت کند؟سپس کلاس مشتقی برای کارمند در نظر بگیرید که میزان حقوق کارمند را با کسر مالیات محسابه کند!
حقوق کمتر از یک میلیون معاف از مالیات
حقوق بین یک میلیون تا دو میلیون 10درصد مالیات
و حقوق بیشتر از دومیلیون پانزده در صد مالیات
ممنون میشم کمکم کنید