در این جلسه از آموزش ++C به بررسی وراثت در ++C می پردازیم. یکی از مهمترین مفاهیم برنامهنویسی شیگرا وراثت (inheritance) میباشد. وراثت اجازه میدهد که یک کلاس را برحسب یک کلاس دیگر تعریف کنیم، موجب آسانتر شدن ساخت و نگهداری یک برنامه میگردد. این مفهوم همچنین موجب استفاده مجدد از کدها و پیادهسازی سریعتر آنها میشود.
برنامهنویس میتواند هنگام نوشتن یک کلاس، به جای نوشتن داده و توابع عضو جدید، شرایطی اتخاد کند که کلاس جدید، اعضای یک کلاس از پیش موجود را به ارث ببرد. این کلاس از پیش موجود کلاس پایه (base class) نامیده میشود، و کلاس جدید، کلاس مشتق شده (derived class) نامیده میشود.
ایده وراثت یک رابطه از نوع «یک … است» (is a) میباشد. برای مثال، پستاندارد یک حیوان است، سگ یک پستاندار است بنابراین سگ همچنین یک حیوان است و الی آخر.
کلاس پایه و مشتق شده
یک کلاس ممکن است از بیش از یک کلاس مشتق شده باشد، یعنی داده و توابع را از چندین کلاس پایه به ارث گرفته باشد. هنگام تعریف یک کلاس مشتق شده، از یک لیست کلاس اشتقاقی (class derivation list) برای مشخص کردن کلاسهای پایه استفاده میکنیم. لیست کلاس اشتقاقی یک یا چند کلاس پایه دارای شکل زیر است.
class derived-class: access-specifier base-class
که در آن access-specifier میتواند public، protected یا private باشد، و base-class نام یک کلاس از پیش تعریف شده است. اگر access-specifier تعیین نشود، به صورت پیش فرض private خواهد بود.
کلاس پایه Shape و کلاس مشتق شده آن Rectangle را در مثال زیر ملاحظه کنید.
#include <iostream> using namespace std; // Base class class Shape { public: void setWidth(int w) { width = w; } void setHeight(int h) { height = h; } protected: int width; int height; }; // Derived class class Rectangle: public Shape { public: int getArea() { return (width * height); } }; int main(void) { Rectangle Rect; Rect.setWidth(5); Rect.setHeight(7); // Print the area of the object. cout << "Total area: " << Rect.getArea() << endl; return 0; }
با اجرای کد فوق، خروجی زیر تولید میشود.
Total area: 35
کنترل دسترسی و وراثت
یک کلاس مشتق شده میتواند به همه اعضای غیرخصوصی (non-private) کلاس پایهاش دسترسی پیدا کند. بنابراین اعضای کلاس پایه که نباید برای توابع کلاس مشتق شده قابل دسترسی باشند را باید به صورت private اعلان کرد.
میتوان انواع دسترسی را بر اساس «چه کسی میتواند دسترسی داشته باشد؟» به صورت زیر تعریف کرد.
دسترسی |
public |
protected |
private |
خود کلاس |
بله |
بله |
بله |
کلاسهای مشتق شده |
بله |
بله |
خیر |
کلاسهای خارجی |
بله |
خیر |
خیر |
یک کلاس مشتق شده، همه متدهای کلاس پایه را به ارث میبرد به غیراز:
- سازندهها، تخریب کنندهها و سازنده کپیهای کلاس پایه
- عملگرهای اورلود شده کلاس پایه
- توابع دوست کلاس پایه
انواع وراثت
هنگام اشتقاق یک کلاس از یک کلاس پایه، کلاس پایه میتواند به صورت public، protected یا private بیان شود. نوع وراثت با access-specifierای که در بالا توضیح دادیم مشخص میگردد.
از وراثت نوع protected یا private به ندرت استفاده میشود، اما وراثت public متداول است. هنگام استفاده از انواع مختلف وراثت، قواعد زیر حاکم هستند:
- وراثت عمومی: هنگام اشتقاق یک کلاس از یک کلاس پایه عمومی، اعضای عمومی کلاس پایه به اعضای عمومی کلاس مشتق شده بدل شده و اعضای محافظت شده کلاس پایه به اعضای محافظت شده کلاس مشتق شده تبدیل میشوند. به اعضای خصوصی یک کلاس هرگز نمیتوان از طریق یک کلاس مشتق شده دسترسی داشت، اما میتوان با فراخوانی اعضای عمومی یا محافظت شده کلاس پایه به آنها دسترسی یافت.
- وراثت محافظت شده: هنگام مشتق گرفتن از یک کلاس پایه محافظت شده، اعضای عمومی و محافظت شده کلاس پایه به اعضای محافظت شده کلاس مشتق شده بدل میشوند.
- وراثت خصوصی: هنگام مشتق گرفتن از یک کلاس پایه خصوصی، اعضای عمومی و محافظت شده یک کلاس پایه به اعضای خصوصی کلاس مشتق شده تبدیل میشوند.
وراثت چندگانه (Multiple Inheritance)
یک کلاس ++C میتواند از بیش از یک کلاس اعضا را به ارث بگیرد. ساختار آن در زیر آمده است.
class derived-class: access baseA, access baseB....
در این ساختار access میتواند public، protected یا private بوده که به همه کلاسها تعلق میگیرد و این کلاسها با کاما از هم جدا میشوند. اجازه دهید مثال زیر را با هم ملاحظه کنیم.
#include <iostream> using namespace std; // Base class Shape class Shape { public: void setWidth(int w) { width = w; } void setHeight(int h) { height = h; } protected: int width; int height; }; // Base class PaintCost class PaintCost { public: int getCost(int area) { return area * 70; } }; // Derived class class Rectangle: public Shape, public PaintCost { public: int getArea() { return (width * height); } }; int main(void) { Rectangle Rect; int area; Rect.setWidth(5); Rect.setHeight(7); area = Rect.getArea(); // Print the area of the object. cout << "Total area: " << Rect.getArea() << endl; // Print the total cost of painting cout << "Total paint cost: $" << Rect.getCost(area) << endl; return 0; }
با اجرای کد فوق، خروجی زیر حاصل میشود
Total area: 35 Total paint cost: $2450
منبع: ترجمه از سایت tutorialspoint.com
امیدواریم آموزش وراثت در ++C براتون مفید واقع شده باشه. در جلسه بعدی به بررسی Overloading خواهیم پرداخت.
اگر این نوشته برایتان مفید بود لطفا کامنت بنویسید.