سلام و درودی دوباره به برنامه نویسان رزدینو بعد از مبحث سطوح دسترسی نوبت میرسه به مبحث وراثت😃. مبحث وراثت یا ارث بری در تمام زبانهای برنامه نویسی سطح بالا از بیشترین اهمیت برخودار است. وراثت در ++C هم نکات خود را دارد که در ادامه با هم بررسی میکنیم.
وراثت یا ارث بری به چه معناست؟
یک پدر و پسر را در نظر بگیرید. پسر ویژگیهایی دارد که دقیقا از پدرش به ارث برده است. از طرفی، پسر علاوه بر خصوصیات پدر، ویژگیهای منحصر به فرد خودش را هم داراست. در زبانهای برنامه نویسی هم دقیقا وراثت همین مفهموم را دارد. به این صورت که ما یک کلاس تعریف میکنیم که یکسری خصوصیات دارد (به این کلاس اصطلاحا کلاس پدر گفته میشود). سپس کلاس دیگری تعریف میکنیم (کلاس پسر) که دقیقا خصوصیات کلاس پدر را دارد و همچنین میتواند خصوصیات جدیدی را نیز به آن اضافه کرد. در ادامه به بررسی مفهوم وراثت در ++c خواهیم پرداخت.
همانطور که در شکل بالا میبینید، نوشتههای سیاه رنگ به فرزندان به ارث رسیده است. علاوه بر اینکه هر کدام از آنها خصوصیات، رفتارها و مهارتهای مربوط به خودشان را دارند (نوشتههای قرمز رنگ).
وراثت در ++C
فرم کلی ارث بری بصورت زیر است:
1 2 3 4 |
class نام کلاس پدر نوع دسترسی : نام کلاس پسر { } |
با کلمه class کلاس پسر را تعریف میکنیم که توسط علامت : از کلاس پدر ارث بری میکند. ابتدا مثالهای مربوط به وراثت را بررسی کرده و در آخر در مورد نوع دسترسی که شبیه به سطوح دسترسی آموزش سیزدهم است، توضیحاتی را خواهیم داد. برای اینکه مفهموم کامل جا بیفته یه مثال ساده میزنم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class A { public: int x; int y; std::string Show(); }; std::string A::Show() { std::string message; message = "x = " + std::to_string(x) + " and y = " + std::to_string(y); return message; } |
کلاس A دو فیلد دارد که هر دو int و سطح دسترسی آنها public است. یک متد بنام Show هم دارد که مقادیر x و y را بصورت یک جمله در رشته message ریخته و برمیگرداند.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class B : public A { public: int z; std::string Show(); }; std::string B::Show() { std::string message; message = "x = " + std::to_string(x) + " and y = " + std::to_string(y) + " and z = " + std::to_string(z); return message; } |
سپس کلاس B را تعریف کردیم که از کلاس A ارث بری کرده است. در اینجا کلاس B تمام خصوصیات کلاس A اعم از فیلدهای x و y و متد Show را دارد. علاوه بر اینکه خود نیز دارای خصوصیتی جدیدی بنام z است.
نکته: کلاس A دارای متد Show است. اگر کلاس B متد Show را نداشته باشد، دقیقا متد Show از A را به ارث میبرد. اما اگر در کلاس B دقیقا متدی به نام Show تعریف کنیم، دیگر از کلاس A متد Show را به ارث نمیبرد و از متد جدید استفاده میکند. به این مفهموم بازنویسی یا Override متد گفته میشود.
با این تفاسیر به برنامه داخل main دقت کنید:
1 2 3 4 5 6 7 8 9 10 11 12 |
A a = A(); B b = B(); a.x = 5; a.y = 6; ////////////// b.x = 1; b.y = 2; b.z = 3; ////////////// cout << a.Show() << endl; cout << b.Show() << endl; |
دو شیء بنامهای a و b بترتیب از A و B ساختیم. دقت کنید که a فقط دو فیلد x و y را دارد که آنها را مقداردهی کردیم. اما چون B از A ارث بری کرده است، در شی b علاوه بر فیلد z، فیلدهای x و y نیز به آن به ارث رسیده است. پس هر سه فیلد شی b را هم مقدار دادیم. در نهایت با اجرای متدهای Show هرکدام پیغامی روی کنسول چاپ میشود.
1 2 3 |
x = 5 and y = 6 x = 1 and y = 2 and z = 3 |
تذکر: اگر متد Show در کلاس B حذف شود، متد Show موجود در A را به ارث میبرد. در این صورت با اجرای main خروجی بصورت زیر تغییر میکند:
1 2 3 |
x = 5 and y = 6 x = 1 and y = 2 |
نوع دسترسی در وراثت
در اوایل این پست به نوع دسترسی اشاره کردیم. نوع دسترسی همانند سطوح دسترسی آموزش سیزدهم، می تواند private، protected و یا public باشد.
- نوع دسترسی Public: اگر دسترسی از نوع public باشد، تمام عناصر public کلاس پدر بصورت public در پسر مشتق میشود و عناصر protected پدر بصورت protected در پسر ظاهر میشوند.
- نوع دسترسی Protected: اگر نوع دسترسی به صورت protected تعریف شود، عناصر public و protected کلاس پدر همگی بصورت protected کلاس پسر در میآیند.
- نوع دسترسی Private: و در آخر اگر دسترسی را از نوع private تعریف کرده باشیم، خصوصیات public و protected کلاس پدر به عنوان عناصر private در کلاس پسر مشتق خواهند شد.
نکته: خصوصیات private کلاس پدر تحت هیچ شرایطی به کلاسهای دیگر به ارث نمیرسند. این خصوصیات تنها مختص خود کلاس پدر بوده و فقط داخل همان کلاس در دسترس میباشند.
برای درک بهتر موضوع به کد زیر دقت کنید:
1 2 3 4 5 6 7 8 9 |
class A { public: int x; protected: int y; private: int z; } |
کلاس A دارای سه فیلد است که به ترتیب سطح دسترسی public و protected و private دارند. کلاس B را به این صورت مینویسیم:
1 2 3 4 5 |
class B : private A { public: int w; } |
در کد فوق تمام عناصر کلاس A بصورت private در B به ارث میرسند. خود کلاس B هم یک فیلد بنام w با سطح دسترسی public دارد. در نتیجه کلاس B سه فیلد دارد که فیلدهای x و y بصورت private و فیلد w بصورت عمومی است. اگر برنامه main بصورت زیر باشد:
1 2 3 4 |
B b = B(); b.x = 8; b.w = -26; |
با اجرای برنامه، کامپایلر ارور میدهد چون سطح دسترسی فیلد x بصورت private است و نمیتوان از شیء ساخته شده از آن، مقداری را خواند یا نوشت.
به عنوان مثال بعدی کلاس B را به صورت زیر مینویسیم:
1 2 3 4 5 |
class B : public A { public: int w; } |
متغیر z که همانند مثال قبل به ارث نمیرسد چون private است. متغیر y با سطح دسترسی protected به B ارث برده میشود و x هم با سطح دسترسی public در B قرار میگیرد. حال اگر برنامه main مانند مثال قبل اجرا شود، چون سطح دسترسی x از private به public تغییر کرده است، کامپایلر بدون هیچگونه مشکلی برنامه را بیلد میکند.
بحث وراثت در ++C بود، به پایان رسید و امیدوارم موثر بوده باشه بخش پایانی مبحث مجموعهها هست. هر سوال و یا اشکالی هست لطفا زیر همین پست کامنت بزارید تا تیم رزدینو پاسخگوی شما عزیزان باشه. با ما در مطالب بعدی همراه باشید…