شکل سوم ارثبری، ارثبری سلسلهمراتبی در سیشارپ است
درسی شارپ ، ارثبری سلسلهمراتبی (Hierarchical Inheritance) یک الگوی کاربردی است که در آن چندین کلاس فرزند از یک کلاس والد مشترک ارثبری میکنند. این روش به شما کمک میکند تا از تکرار کد جلوگیری کنید و منطق مشترک را در یک مکان متمرکز کنید.
مثال کاربردی: دنیای حیوانات
فرض کنید کلاس پایه Animal را داریم که دارای متد عمومی Eat() میباشد. سپس دو کلاس Dog و Cat از این کلاس ارثبری میکنند و هرکدام رفتارهای خاص خود Bark() و Meow() را اضافه میکنند:
public class Animal
{
public void Eat() => Console.WriteLine("Eating...");
}
public class Dog : Animal
{
public void Bark() => Console.WriteLine("Barking...");
}
public class Cat : Animal
{
public void Meow() => Console.WriteLine("Meowing...");
}
نحوه استفاده : وقتی یک شیء از نوع Cat یا Dog ایجاد میکنید، میتوانید هم از متدهای کلاس والد (Animal) و هم از متدهای اختصاصی خود استفاده کنید:
var cat = new Cat();
cat.Eat(); // خروجی: "Eating..." (از Animal)
cat.Meow(); // خروجی: "Meowing..." (مخصوص Cat)
var dog = new Dog();
dog.Eat(); // خروجی: "Eating..."
dog.Bark(); // خروجی: "Barking..."
چرا ارثبری سلسلهمراتبی مفید است؟
کاهش تکرار کد: متدهای مشترک (مثل Eat() فقط یک بار نوشته میشوند.
افزایش خوانایی و نظم: ساختار کد شفافتر و منطقیتر میشود.
سهولت در نگهداری: تغییر در کلاس والد به صورت خودکار به تمام کلاسهای فرزند اعمال میشود.
اگر میخواهید یک معماری منعطف و تمیز داشته باشید، ارثبری سلسلهمراتبی میتواند یکی از بهترین انتخابها باشد.
در این بخش در ادامه پست فبلی به سراغ معرفی نوع دیگری از ارثبری می رویم به نام ارثبری چندسطحی (Multilevel Inheritance) :
در مثال زیر یک کلاس از کلاسی ارثبری میکند که خودش از کلاس دیگری ارثبری کرده است.
public class Animal
{
public void Eat() => Console.WriteLine("Eating...");
}
public class Mammal : Animal
{ // سطح اول
public void Walk() => Console.WriteLine("Walking...");
}
public class Dog : Mammal
{ // سطح دوم
public void Bark() => Console.WriteLine("Barking...");
}
// روش استفاده
var dog = new Dog();
dog.Eat(); // از Animal
dog.Walk(); // از Mammal
dog.Bark();
در مثال بالا ، دلیل اینکه این کد بهعنوان یک نمونه از ارثبری (Inheritance) و بهویژه ارثبری چندسطحی (Multilevel Inheritance) در نظر گرفته میشود، به ساختار سلسلهمراتبی کلاسها و نحوه دسترسی به متدها برمیگردد. بیایید این موضوع را مرحله به مرحله بررسی کنیم:
1 - تعریف ارثبری
ارثبری در برنامهنویسی شیءگرا به این معناست که یک کلاس (کلاس فرزند) میتواند ویژگیها و رفتارهای یک کلاس دیگر (کلاس والد) را به ارث ببرد. در اینجا، کلاس Dog بهطور مستقیم از کلاس Mammal ارثبری میکند و کلاس Mammal نیز بهطور مستقیم از کلاس Animal ارثبری کرده است . این زنجیره ارثبری، یک ارثبری چندسطحی را تشکیل میدهد:
2 - چرا این ارثبری است، حتی اگر متد همنام استفاده نشده باشد؟
برای جلوگیری از ایجاد سوء تفاهم در معنی ارثبری باید بگویم که ارثبری به معنای استفاده از متدهای همنام یا بازنویسی (Override) نیست. ارثبری صرفاً به این معناست که کلاس فرزند به تمام اعضای عمومی (public) و محافظتشده (protected) کلاس والد دسترسی دارد، مگر اینکه آنها را بازنویسی یا مخفی کند. در این مثال:
وقتی یک شیء از کلاس Dog میسازید ، این شیء به تمام متدهای عمومی کلاسهای والد خود (Eat از Animal و Walk از Mammal) به علاوه متد خودش (Bark) دسترسی دارد. این دسترسی به متدها از طریق ارثبری ممکن شده است، حتی اگر هیچ متدی بازنویسی یا همنام نشده باشد.
3 - ارثبری چندسطحی در عمل
در این کد، وقتی شما دستورات زیر را اجرا میکنید:
var dog = new Dog();
dog.Eat(); // خروجی: Eating...
dog.Walk(); // خروجی: Walking...
dog.Bark(); // خروجی: Barking...
این نشان میدهد که Dog بهطور غیرمستقیم از Animal (از طریق Mammal) ارثبری کرده است. این زنجیره سلسلهمراتبی دقیقاً همان چیزی است که ارثبری چندسطحی را تعریف میکند.
4 - جمعبندی
ارثبری به معنای انتقال قابلیتها از کلاس والد به کلاس فرزند است، نه لزوماً استفاده از متدهای همنام یا بازنویسی آنها. در این مثال، Dog بهطور کامل از Mammal و بهطور غیرمستقیم از Animal ارثبری میکند و این ساختار چندسطحی باعث میشود که بتوانید به متدهای هر سه سطح دسترسی داشته باشید. به همین دلیل، این کد بهعنوان یک نمونه از ارثبری چندسطحی در نظر گرفته میشود.
در این بخش به معرفی موضوع ارثبری در زبان برنامهنویسی سیشارپ میپردازیم و در پستهای بعدی، انواع مختلف ارثبری را با مثالهای بیشتری بررسی خواهیم کرد.
ارثبری به این معناست که یک کلاس میتواند از متدها، ویژگیها یا رفتارهای تعریفشده در کلاس دیگر استفاده کند. به این فرآیند، ارثبری از یک کلاس گفته میشود. کلاسی که متدها و ویژگیهایش به ارث برده میشود، کلاس والد یا پایه نام دارد و کلاسی که از آنها استفاده میکند، کلاس فرزند یا مشتق نامیده میشود.
زبان سیشارپ تنها از ارثبری یگانه (Single Inheritance) پشتیبانی میکند، یعنی هر کلاس فرزند فقط میتواند از یک کلاس والد ارثبری کند. اما ارثبری چندگانه (Multiple Inheritance) به صورت مستقیم در سیشارپ پشتیبانی نمیشود. برای جبران این محدودیت، سیشارپ از رابطها (Interfaces) استفاده میکند که جایگزینی بهتر و قوی تری برای ارثبری چندگانه هستند و در پستهای بعدی به طور مفصل بررسی خواهند شد.
در این جلسه، صرفاً به یک مثال ساده از ارثبری یگانه بین دو کلاس اکتفا میکنیم:
public class Animal
{
public void Eat() => Console.WriteLine("Eating...");
}
public class Dog : Animal
{
public void Bark() => Console.WriteLine("Barking...");
}
// کد تست
var dog = new Dog();
dog.Eat(); // خروجی: Eating...
dog.Bark(); // خروجی: Barking...
در مثال بالا، کلاس Dog از کلاس Animal ارثبری کرده و میتواند از متد Eat استفاده کند، ضمن اینکه متد اختصاصی خودش یعنی Bark را نیز دارد. در پستهای بعدی، به انواع دیگر ارثبری و کاربردهای آنها خواهیم پرداخت.
چگونه می توانیم در یک متد که از یک کلاس والد به ارث برده ایم درون کلاس فرزند تغییراتی اعمال کنیم ؟
می دانید در صورتی که یک کلاس از یک کلاس والد ارثبری داشته باشد باید متدهای انتزاعی آن کلاس را درون خود پیاده سازی کند. حالا که مجبور به پیاده سازی هستیم چگونه در این متدها متناسب با نیاز خود تغییر ایجاد کنیم ؟
در کد زیر دقت کنید .
class Animal
{
public virtual string Sound() // استفاده از virtual برای اجازه بازنویسی
{
return "صدای حیوان";
}
}
class Dog : Animal
{
public override string Sound() // بازنویسی متد با همان نام و پارامترها
{
return "واق واق";
}
}
ما در کلاس Animal متدی به نام sound داریم که با کلمه کلیدی virtual مجوز ایجاد تغییر در آن توسط کلاس های مشتق را داده ایم . در کلاس Dog که از کلاس Animal ارثبری می کند نیز متد sound را داریم که در اینجا با کلمه کلیدی override اعلام می کند که من در متد کلاس والد تغییراتی می دهم. در کد زیر نیز روش استفاده از این کلاس را مشاهده می کنید.
private void button2_Click(object sender, EventArgs e)
{
Animal myDog = new Dog();
label1.Text = myDog.Sound() ;
}