در شیگرایی میتونیم یه کلاس تعریف کنیم و چند تا فرزند براش تعریف کنیم مثلاً به صورت زیر
class Shape
{
};
class Rectangle : public Shape
{
};
class Circle : public Shape
{
};
حالا فرض کنیم تابعی داریم که در هر دو تا فرزند وجود داره ولی در هر فرزند به یه صورت مجزا عمل میکنه مثلاً تابع رسم
class Shape
{
};
class Rectangle : public Shape
{
void draw() const
{
}
};
class Circle : public Shape
{
void draw() const
{
}
};
خب در این صورت میشه برای هر دو تا شی تعریف شده رسم رو فراخوان کرد
Rectangle R();
R.draw();
Circle C();
C.draw();
یه چیزی داریم توی شیگرایی به نام نوع پویا یا نوع داینامیک. یعنی یه اشارهگر به والد میتونه به فرزند اشاره کنه
Shape *S1 = new Circle();
Shape *S2 = new Rectangle();
حالا در صورتی که بخوایم تابع رسم رو برای دو اشارهگر بالا فراخوانی کنیم اشکالی وجود داره. تابع برای کلاس Shape
تعریف نشده. بنابراین باید برای Shape
هم تابع draw()
رو تعریف کنیم.
class Shape
{
void draw() const
{
}
};
اما در صورتی که برای S1
و S1
تابع رسم رو فراخوانی کنیم تابعی که اجرا میشه، تابع draw
مربوط به Shape
هست نه Rectangle
یا Circle
.
مشکل رو با تابع مجازی یا virtual
رفع میکنیم. تابع مجازی در کلاس والد معرفی میشه بدون پیادهسازی و همون تابع در فرزندها تعریف میشه با پیادهسازی. بنابراین وقتی تابع مجازی اجرا بشه، تابع مربوط به فرزند مربوط اجرا میشه
S1->draw();
تابع draw
مربوط به کلاس Circle
رو اجرا میکنه
S2->draw();
تابع draw
مربوط به کلاس Rectangle
رو اجرا میکنه
هیچ پژوهش انسانی نمیتواند ادعای علمی بودن داشته باشد، مگر اینکه از برهان ریاضی برخوردار باشد (لئوناردو داوینچی)