PDA

View Full Version : دلیل استفاده از متد virtual



seied javad
چهارشنبه 23 اردیبهشت 1394, 05:32 صبح
لام خسته نباشید
یک برنامه ساده ای دارم با دو کلاس car و sport car که هر کدوم متغیر هایی دارند که یکی از متغیر ها speed می باشد هر کدوم از کلاس ها عملیاتی را انجام میدهند که یکیش عملیات gaz می باشد که هر وقت این عملیات انجام داده میشود در کلاس car سرعت(speed) یک واحد و در کلاس sport car دو واحد افزایش پیدا میکند. این دو کلاس از هم ارث می برند کلاس car کلاس پدر و کلاس sport car کلاس فرزند است.
سوال:
وقتی میخواهیم یک عملیات را درکلاس فرزنددوباره بنویسیم اونو در کلاس پدر virtual و در کلاس فرزند override میکنیم اما چرا؟ من وقتی این دو کلمه را برمیدارم بازم برنامه به درستی اجرا میشه و همون خروجی را میده.

نمونه برنامه را هم میتونید از لینک زیر دانلود کنید .
دانلود (http://uploadboy.com/4n0boy19n08h.html)


131179

131178
تشکر

RmeXXXXXXXXX
پنج شنبه 24 اردیبهشت 1394, 23:17 عصر
کد ک دانلود نشد. کاش همینجا آپلود می کردین.
ولی میتونم حدس بزنم که منظورتون چیه!

public class Car
{
protected int _speed;
public int Speed { get { return _speed; } }

public virtual void Gaz()
{
_speed += 1;
}
}

public class SportCar : Car
{
public override void Gaz()
{
_speed += 2;
}
}

تا اینجاش درست. ولی اگه virtual و override رو هم نذاریم باز تأثیری در نتیجه نداره
مگر
مگر بخواهیم این چنین کدی بنویسیم:

static void Main(string[] args)
{
Car normalCar = new Car();
normalCar.Gaz();
Console.WriteLine(normalCar.Speed);

normalCar = new SportCar();
normalCar.Gaz();
Console.WriteLine(normalCar.Speed);

Console.ReadKey();

خروجی:
1
2
دقت کنید که متغیر normalCar از نوع Car هست ولی بار اول 1 و بار دوم 2 رو نشون میده. دلیلش اینه که در بار دوم ما رفتار کلاس پدر رو بازنویسی کردیم توسط virtual و override شاید اولش یکم گیج کننده بیاد ولی خیلی ساده است.

SabaSabouhi
شنبه 26 اردیبهشت 1394, 11:26 صبح
سلام
دوستمون RmeXXXXXX با مثال توضیح دادن، من هم ضمن تایید نوشته‌ی ایشون کمی بهش اضافه می‌کنم.

زمانی هست که ما نیاز به تولید کلاس‌هایی داریم که یک BaseClass دارن. تمام این کلاس‌ها نیاز دارن که
یک متد داشته باشن برای یک محاسبه‌ی خاص. حالا دو حالت پیش میاد:
1. فرمول این محاسبه تو اغلب این کلاس‌ها مشابه هست.
تو این حالت یه متد Virtual می‌گذاریم و محاسبه رو توش انجام می‌دیم. فقط در کلاس‌هایی که فرمول در اون‌ها متفاوت هست متد رو با Override بازنویسی می‌کنیم.
2. فرمول در تمام کلاس‌ها متفاوت هست.
در این حالت تو کلاس base متد رو به صورت abstract می‌نویسیم و در کلاس‌ها اون رو با Override پیاده سازی می‌کنیم.

اما این کار چه خاصیتی داره؟ ابتدا یک مثال می‌زنم.
ما یه کلاس پایه داریم به نام شکل هندسی که دو تا مقدار ارتفاع و قاعده داره.
یک متد مساحت هم داریم که virtual هست و قاعده رو در ارتفاع ضرب می‌کنه.
حالا کلاس‌های مثلث، مربع و مستطیل رو تولید می‌کنیم.

برای کلاس‌های مربع و مستطیل نیازی به نوشتن دوباره‌ی متد مساحت نیست، همون متد اصلی داره کارش رو انجام می‌ده
اما برای مثلت باید متد اصلی رو اصلاح کنیم. اینجا از override استفاده می‌کنیم. و حاصل ضرب ارتفاع و قاعده رو نصف می‌کنیم.

امتیازی که قید کردن override داره.
اگه این کلمه‌ی کلیدی رو استفاده نکنیم، دقیقاً مشابه این هست که کلمه‌ی کلیدی new رو استفاده کرده باشیم.
این کلمه‌ی کلیدی به کامپایلر می‌گه که این متد مساحت هیچ ربطی به متد مساحت کلاس پایه نداره. و ظاهراً هر دو به یک شکل کار می‌کنن.
اما اگه کار رو درست انجام بدیم ( قید کردن کلمه‌ی کلیدی override ) تو نوشتن متدهای مشترک خیلی به ما کمک می‌کنه.

مثلاً ممکنه ما یه کلاس اشکال سه بعدی بنویسیم که برای اون یک property از نوع شکل هندسی داشته باشیم که در واقع
قاعده‌ی شکل سه بعدی ما رو تشکیل می‌ده.
برای متد محاسبه‌ی حجم شکل سه بعدی باید مساحت شکل هندسی قاعده در ارتباط این حجم ضرب بشه.
هنگامی که متد محاسبه‌ی سطح شکل هندسی قاعده رو فراخوانی می‌کنیم. اگه شکلمون مربع بود، متد کلاس پایه
فراخوانی می‌شه ( چون کلاس مربع این متد رو پیاده‌سازی نکرده )
اما اگه شکل قاعده مثلث بود، متد override شده در کلاس مثلث فراخونی می‌شه.

این خاصیت به‌ویژه هنگام ساخت کنترل بسیار کارایی داره و به‌تره که عادت کنی ازش استفاده کنی.
امیدوارم که توضیحی که دادم مساله رو برات بیشتر روشن کرده باشه.

صبا صبوحی

seied javad
جمعه 08 خرداد 1394, 21:43 عصر
سلام
ممنون خیلی کمکم کرد