وراثت یا ارث بری (Inheritance) یکی از اصول چهارگانه برنامه نویسی شی گرابرنامه نویسی شی گرا چیست؟ شی گرایی چیست؟این صفحه عالی به معرفی برنامه نویسی شی گرا پرداخته و توضیح داده شی گرایی یا همان object oriented یا OPP چیست؟ همچنین مزایای برنامه نویسی شی گرا را بیان کرده یا Object Oriented Programming (OOP) است. حتماً مفهوم وراثت را در دنیای واقعی میدانید. رنگ چشم، رنگ مو، قد، نوع مو و خیلی از موارد دیگر بدن ما از والد ما به ارث رسیده است. علاوه بر این که ظاهر و باطن ما بسیار شبیه به والد ما است، خیلی از موارد دیگری وجود دارد که مختص به خودمان است، مثلا علاقه به یک ورزش و یا عرصهای که در آن حرفهای هستیم؛ همچنین اثر انگشت هر یک از ما منحصربهفرد است. در دنیای برنامه نویسیبرنامه نویسی کامپیوتر چیست و چطور می توانید یک برنامه نویس موفق شوید؟در عصر فعلی برنامهنویسی یکی از پرطرفدارترین شغلهای دنیاست، دغدغهای افرادی که میخواهند در مسیر برنامهنویس شدن قدم بردارند این است که نمیدانند از کجا باید شروع کنند، در این صفحه هر آن چه برای تبدیل شدن به یک برنامه نویس حرفه ای نیاز دارید در اختیارتان قرار گرفته است نیز چنین مفهومی وجود دارد.
کلاس جدید میتواند از کلاسهای دیگر ارث بری کند تا رفتار و صفات آن کلاس را به ارث ببرد؛ همچنین این کلاس جدید قادر است ویژگیها و متدهای جدیدی داشته باشد تا دارای ویژگی های منحصربهفرد خود باشد، به عنوان مثال فرض کنید کلاسی داریم با عنوان وسیله نقلیه که شامل متدهای روشن کردن، خاموش کردن، شتاب گرفتن و... است. حال فرض کنید کلاسی وجود داشته باشد با نام کلاس ماشین که از کلاس وسیله نقلیه ارث بری میکند و خاصیتهای جدیدی مانند باز کردن در، بستن در و روشن کردن چراغ در آن تعریف میشود. خود کلاس ماشین که فرزند کلاس وسیله نقلیه است، قادر است تا والد یک کلاس دیگر مثلا بنز شود (به این عمل، ارث بری سلسله مراتبی میگویند). در کلاس بنز که از کلاس ماشین ارث بری میکند مجدداً ویژگیهای جدیدی مانند تنظیم صندلی خودرو، روشن کردن پارک خودکار و... تعریف میشود. کلاسهای دیگری میتوانند از کلاس وسیله نقلیه ارث بری کنند، مانند کلاس موتورسیکلت و کلاس اتوبوس و... . در اصطلاحات برنامهنویسی شی گرا، به کلاس والد، Superclass و به کلاس فرزند، (کلاس مشتق) Subclass میگویند. در بعضی از متون (معمولا قدیمیتر) ممکن است به کلاس والد کلاس Parent و به کلاس فرزند کلاس Child نیز بگویند. شکل زیر نمای UML مثالهای ذکر شده را نشان میدهد:
انواع ارث بری در برنامه نویسی
در برنامهنویسی، انواع ارث بری وجود دارد که در لیست زیر آمده است:
- ارث بری یگانه یا تکی (Single Inheritance)
- ارث بری چندگانه (Multiple Inheritance)
- ارث بری چندسطحی (Multilevel Inheritance)
- ارث بری ترکیبی (Hybrid Inheritance)
بهطور کلی در عمل دو نوع ارث بری وجود دارد؛ اولین نوع ارث بری، تکی یا Single Inheritance میباشد که در آن کلاسها میتوانند تنها از یک کلاس ارث بری کنند. نوع دیگری نیز وجود دارد با نام ارث بری چندگانه یا Multiple Inheritance که کلاس فرزند از چندین کلاس والد ارث بری میکند. انواع چندسطحی و ترکیبی بهصورت تئوری هستند و این گونه نیست که زبان های برنامه نویسیزبان های برنامه نویسی چیست؟این مقاله عالی توضیح داده که زبان های برنامه نویسی چیست؟ و انواع زبان های برنامه نویسی و بهترین زبان برنامه نویسی برای شروع و پردرآمدترین آنها را معرفی کرده از آنها پشتیبانی کنند یا نکنند. در زبان C++برنامه نویسی سی پلاس پلاس چیست؟ مزایای برنامه نویسی C++؟برنامه نویسی سی پلاس پلاس چیست و چه کاربردی دارد؟ این صفحه عالی به بررسی مزایای برنامه نویسی C++ پرداخته و نمونه هایی از کدهای زبان برنامه نویسی ++C را آورده و پایتون (Python)زبان برنامه نویسی پایتون چیست؟ – نحوه شروع و دلایل محبوبیتزبان برنامه نویسی پایتون (Python) چیست؟ این مقاله عالی به بررسی دلایل محبوبیت پایتون، موارد استفاده از پایتون و نحوه شروع به برنامه نویسی پایتون پرداخته قادر هستیم تا از Multiple Inheritance استفاده کنیم اما زبانهایی مانند زبان جاواجاوا چیست؟ تعریف، معنی و ویژگی های جاوا (java) از 0تا100جاوا یک زبان برنامه نویسی همه منظوره، مبتنی بر کلاس و شی گرا است که برای داشتن وابستگی های پیاده سازی کمتر طراحی شده است، زبان برنامه نویسی جاوا شبیه ++C است یا C#سی شارپ چیست ⚡️سی شارپ به زبان سادهاین صفحه عالی بررسی کرده که سی شارپ چیست و تاریخچه سی شارپ، محیط و ابزارهای سی شارپ، ویژگی های سی شارپ، مزایای سی شارپ و کاربرد و بازار کار سی شارپ را گفته دارای این ویژگی نمیباشند و تنها از Single Inheritance پشتیبانی میکنند؛ البته این به معنی محدود بودن زبانهای ذکر شده نمیباشد. در این زبانها ویژگی دیگری با نام اینترفیس (Interface) وجود دارد که میتواند تا حدودی شبیه به ارثبری چندگانه رفتار کند.
مزایا و معایب ارث بری
با این که ارث بری دارای مزایای فراوانی است و کار برنامهنویسان را بسیار راحتتر میکند، اما دارای معایبی نیز میباشد. در این قسمت مهمترین مزایا و معایب ارث بری را بررسی میکنیم.
مزایای ارث بری
- استفاده مجدد از کد (Code Reusability): ارث بری برنامهنویس را قادر میسازد تا از ویژگیهای کلاس والد استفاده مجدد کند و دیگر نیازی به نوشتن دوباره آن در هر کلاس جدید نباشد. به این خاصیت، Reusability کد میگویند.
- ماژولار بودن (Modularity): با استفاده از خاصیت ارث بری میتوان ساختار یک کد را به صورت ماژول (Module) درآورد. به این ترتیب علاوه بر تولید یک ساختار منسجم، عملیات مربوط به رفع باگمعنی باگ چیست | باگ یعنی چه؟ | انواع باگ های نرم افزاریاین مقاله عالی به توضیح معنی باگ (bug)، معرفی انواع باگ های نرم افزاری، توضیح آنکه چگونه از پدید آمدن باگ جلوگیری کنیم؟ و در نهایت نحوه رفع باگ پرداخته و اشکال زدایی (Debugging)دیباگ چیست؟ معرفی روشها و ابزارهای دیباگینگ(اشکال زدایی)این مقاله عالی مفاهیم دیباگ (debug)، دیباگینگ (Debugging) یا همان اشکال زدایی، دیباگر (Debugger) را معرفی و همچنین روشها و ابزارهای دیباگینگ را بررسی کرده راحتتر شده و خاصیتهای جدید میتوانند در قالب ماژول به کد ما اضافه شوند.
- توسعه پذیری کد (Code Extensibility): ارث بری ما را قادر میسازد تا عملکردهای تازه و توابع جدید را به کلاسهای موجود، بدون ایجاد تغییر در کلاسهای والد اضافه کنیم.
معایب ارث بری
- افزایش پیچیدگی: متاسفانه قابلیت ارث بری در بسیاری از موارد باعث پیچیدگی کدمان میشود، به خصوص زمانی که به صورت سلسله مراتبی از ارث بری استفاده میکنیم؛ همچنین ارتباط میان کلاسها میتواند چالشبرانگیز باشد و در بعضی موارد باعث به وجود آمدن باگ در کد شود.
- جفت شدگی (Tight Coupling): یکی از مشکلاتی که برنامهنویسان در بعضی اوقات با آن دست و پنجه نرم میکنند، جفت شدگی یا اتصال کامل است. به این صورت که کلاسها به هم وابستگی شدید پیدا میکنند. در این موارد تغییر در کلاس والد باعث میشود تمامی کلاسهای فرزندان بهطور ناخواسته تحت تاثیر تغییر در کلاس والد قرار گرفته و دچار تغییر شوند بنابراین باید از همان ابتدای کدنویسیکدنویسی چیست؟ – کد نویسی یعنی چهاین مقاله عالی به بررسی این پرداخته که کد نویسی چیست و مفهوم کد نویسی را بررسی کرده، همچنین تفاوت کدنویسی و برنامه نویسی و کاربرد های کدنویسی را بررسی کرده بسیار مراقب بود.
- انعطاف ناپذیری (Inflexibility): همانطور که در مورد بالا گفته شد، تغییر در کلاس والد باعث تغییر در تمامی کلاسهای فرزندان میشود بنابراین باید قسمتهای مختلفی از کد را تغییر دهیم. بههمین دلیل خاصیت ارث بری باعث میشود تا کد ما از انعطافپذیری کمتری برخوردار باشد.
ارث بری در کدنویسی
تا اینجا به مفاهیم مربوط به ارث بری پرداختیم. بد نیست که کمی ارث بری را در عمل مشاهده کنیم. در کد زیر که یک کد به زبان پایتون است، کلاس Vehicle ساخته شده است و در آن متد display_brand تعریف شده تا برند وسیله نقلیه را نمایش دهد؛ همچنین کلاس Engine با متد start_engine ایجاد شده است. هردو کلاس Vehicle و Engine، والد کلاس Car هستند. در کلاس Car، متدی با نام display_model ساخته شده است تا مدل ماشین را نمایش دهد. در واقع کلاس Car در اینجا از ویژگی Multiple Inheritance استفاده کرده است:
class Vehicle:
def __init__(self, brand):
self.brand = brand
def display_brand(self):
print("Brand:", self.brand)
class Engine:
def start_engine(self):
print("Engine started.")
class Car(Vehicle, Engine):
def __init__(self, brand, model):
Vehicle.__init__(self, brand)
self.model = model
def display_model(self):
print("Model:", self.model)
my_car = Car("Toyota", "Camry")
my_car.display_brand() # Output: Brand: Toyota
my_car.start_engine() # Output: Engine started.
my_car.display_model() # Output: Model: Camry
همانطور که مشاهده میکنید، در شی ساخته شده از کلاس Car، هر سه تابع ذکر شده را فراخوانی کردیم. کد بالا در زبان ++C بهصورت زیر نوشته میشود:
#include <iostream>
using namespace std;
class Vehicle {
public:
string brand;
Vehicle(string brand) {
this->brand = brand;
}
void displayBrand() {
cout "Brand: " brand endl;
}
};
class Engine {
public:
void startEngine() {
cout "Engine started." model = model;
}
void displayModel() {
cout "Model: " model endl;
}
};
int main() {
Car myCar("Toyota", "Camry");
myCar.displayBrand(); // Output: Brand: Toyota
myCar.startEngine(); // Output: Engine started.
myCar.displayModel(); // Output: Model: Camry
return 0;
}
نمونهی کدهای بالا را نمیتوان در زبانهایی مثل سی شارپ پیادهسازی کرد، چرا که زبان سی شارپ همانطور که گفته شد از ارث بری چندگانه پشتیبانی نمیکند اما میتوان کلاس Engine را بهصورت یک اینترفیس در سی شارپاینترفیس در سی شارپ – Interface ها در زبان سی شارپاین مقاله عالی به معرفی اینترفیس در سی شارپ پرداخته و سپس نکاتی پیرامون interface در #C و علت استفاده از interface در زبان #C را بررسی کرده درآورد و آن اینترفیس را در کلاس Car پیادهسازی یا Implement کرد. در این صورت میتوان از متدهای ایجاد شده در اینترفیس Engine در کلاس Car استفاده نمود. کد زیر این مفهوم را نمایش میدهد:
using System;
interface IEngine
{
void StartEngine();
}
class Vehicle
{
protected string brand;
public Vehicle(string brand)
{
this.brand = brand;
}
public void DisplayBrand()
{
Console.WriteLine("Brand: " + brand);
}
}
class Car : Vehicle, IEngine
{
private string model;
public Car(string brand, string model) : base(brand)
{
this.model = model;
}
public void DisplayModel()
{
Console.WriteLine("Model: " + model);
}
public void StartEngine()
{
Console.WriteLine("Engine started.");
}
}
class Program
{
static void Main(string[] args)
{
Car myCar = new Car("Toyota", "Camry");
myCar.DisplayBrand(); // Output: Brand: Toyota
myCar.DisplayModel(); // Output: Model: Camry
myCar.StartEngine(); // Output: Engine started.
}
}
همانطور که مشاهده میکنید در خط 3، اینترفیسی با نام IEngine تعریف شده است و دارای متد StartEngine میباشد که دقیقاً مانند کلاس Engine در کد پایتون و C++ رفتار میکند.
جمعبندی
ارث بری یکی از مفاهیم پرکاربرد و تقریباً ساده در زمینه برنامهنویسی شی گرا است بنابراین تمامی زبانهای شی گرا دارای این ویژگی میباشند. در این مقاله بهطور جامع به بحث در مورد ویژگی ارث بری پرداخته شد و با مثالهای متعدد سعی کردیم تا درک عمیقتری از مفهوم شی گرایی را در خوانندگان به وجود بیاوریم.
مفهوم ارث بری چیست؟
بهطور خلاصه ارث بری مکانیزمی است که بهوسیله آن، یک کلاس ویژگیها و صفات یک کلاس دیگر را به ارث میبرد و قادر است از آنها استفاده کند همچنین امکان ایجاد متدها و ویژگیهای جدید در کلاس جدید نیز وجود دارد.
آیا ارث بری تنها در زبان های شئ گرا وجود دارد؟
بله، ارث بری یکی از ارکان چهارگانه برنامه نویسی شی گرا است بنابراین اگر زبانی (مانند زبان برنامهنویسی C) از شی گرا پشتیبانی نکند، ارث بری دیگر در آن مفهومی نخواهد داشت.
فرق وراثت یگانه و وراثت چندگانه چیست؟
در وراثت یگانه تنها قادر هستیم تا از یک کلاس ارث بری کنیم؛ اما در وراثت چندگانه میتوانیم از تعداد متعددی از کلاسها ارث بری داشته باشیم. بعضی از زبانها تنها از وراثت یگانه پشتیبانی میکنند؛ مانند زبان های Java و C#، اما زبانهایی مانند Python و C++، علاوه بر وراثت یگانه، از وراثت چندگانه نیز پشتیبانی میکنند.