PDA

View Full Version : مقدمه ای بر سی شارپ : قسمت- 15



Vahid_Nasiri
چهارشنبه 29 مرداد 1382, 00:37 صبح
ارث بری (Inheritance) :

ارث بری یکی از مفاهیم اولیه ی برنامه نویسی شیء گرا می باشد. با استفاده از آن استفاده مجدد از کد موجود به نحوی مؤثر میسر می گردد و صرفه جویی قابل توجهی را در زمان برنامه نویسی پدید می آورد. به کد زیر دقت کنید :


using System;

public class ParentClass
{
public ParentClass()
{
Console.WriteLine("Parent Constructor.");
}
public void print()
{
Console.WriteLine("I'm a Parent Class.");
}
}

public class ChildClass : ParentClass
{
public ChildClass()
{
Console.WriteLine("Child Constructor.");
}
public static void Main()
{
ChildClass child = new ChildClass();
child.print();
}
}

Output:
Parent Constructor.
Child Constructor.
I'm a Parent Class.

کد فوق از دو کلاس استفاده می کند. کلاس بالایی ParentClass و کلاس اصلی ChildClass می باشد. کاری که انجام شده است استفاده از کدهای کلاس والد ParentClass در کلاس بچه (!) ChildClass می باشد. برای اینکه ParentClass را بعنوان کلاس پایه برای ChildClass معرفی کنیم به صورت زیر عمل شد :


public class ChildClass : ParentClass

کلاس پایه با استفاده از معرفی کولون ":" ، پس از کلاس مشتق شده تعریف می شود. در سی شارپ تنها ارث بری یگانه پشتیبانی می شود. بنابراین تنها یک کلاس پایه را برای ارث بری می توان تعریف کرد.

ChildClass دقیقا توانایی های ParentClass را دارا است. بنابراین می توان گفت ChildClass همان ParentClass است. برای مثال در کد فوق ChildClass دارای متد print نمی باشد اما آنرا از کلاس ParentClass به ارث برده است و در متد Main برنامه از آن استفاده گردیده است.

هنگام ساختن یک شیء از کلاس مشتق شده (derived) ، ابتدا یک نمونه از کلاس والد خود بخود ساخته می شود. این مورد در خروجی کد فوق هنگامی که متدهای سازنده ها روی صفحه چاپ شده اند قابل مشاهده است.



تبادل اطلاعات بین کلاس والد و کلاس فرزند :

به مثال زیر دقت کنید :


using System;

public class Parent
{
string parentString;

public Parent()
{
Console.WriteLine("Parent Constructor.");
}

public Parent(string myString)
{
parentString = myString;
Console.WriteLine(parentString);
}

public void print()
{
Console.WriteLine("I'm a Parent Class.");
}
}

public class Child : Parent
{
public Child() : base("From Derived")
{
Console.WriteLine("Child Constructor.");
}

public void print()
{
base.print();
Console.WriteLine("I'm a Child Class.");
}

public static void Main()
{
Child child = new Child();
child.print();
((Parent)child).print();
}
}

Output:
From Derived
Child Constructor.
I'm a Parent Class.
I'm a Child Class.
I'm a Parent Class.

کلاس فرزند با کلاس والد در هنگام instantiation می تواند تبادل اطلاعات کند. همانطور که در مثال فوق بارز است با استفاده از کلمه ی کلیدی base ، کلاس فرزند تابع سازنده ی کلاس والد را فراخوانی کرده است. اولین خط خروجی بیانگر این موضوع است.

گاهی از اوقات ما می خواهیم تابعی را که در کلاس والد تعریف شده است را در کلاس فرزند با تعریف دیگری و مخصوص به خودمان ارائه دهیم. در اینصورت تابع تعریف شده در کلاس فرزند ، تابع هم نام والد را مخفی خواهد کرد و دیگر آن تابع والد فراخوانی نخواهد گردید. در این حالت تنها یک راه برای دسترسی به تابع اصلی والد وجود دارد و آن استفاده از base. می باشد که در کد فوق پیاده سازی شده است.
با استفاده از base. می توان به تمام اعضای public و یا protected کلاس والد از درون کلاس فرزند دسترسی داشت.
راه دیگری که برای این منظور وجود دارد در آخرین خط کد فوق در متد Main پیاده سازی شده است :


((Parent)child).print();

برای تبدیل نوع های مختلف در سی شارپ می توان از پرانتز و سپس ذکر نوع اصلی استفاده کرد به این عمل casting و یا boxing هم می گویند. در کد فوق درحقیقت child به نوعی از parent تبدیل شده است. بنابراین مانند این است که یک نمونه از کلاس والد متد print همان کلاس را فراخوانی می کند.

Kambiz
چهارشنبه 29 مرداد 1382, 03:26 صبح
بر اساس تعریف پلی‌مرفیسم باید در کد زیر حتی با وجود Type Cast کردن child به کلاس Parent باز متد print مربوط به کلاس Child فراخوانی بشود.

Child child = new Child();
((Parent)child).print();
کد زیر را در نظر بگیرید:

Parent parent = new Child();
parent.print();
مسلما" در این کد متد print مربوط به کلاس Child فراخوانی می‌شود٬ و از طرفی این کد مشابه همان Type Cast است. با این حساب آیا <span dir=ltr>C#</span> در این مورد با دیگر زبانهای شی‌گرا متفاوت است؟

Vahid_Nasiri
چهارشنبه 29 مرداد 1382, 17:28 عصر
در مورد پلی مرفیسم که موضوع مقاله ی بعدی خواهد بود کاملا حق با شما است:
بحث پلی مرفیسم بر مبنای تعریف یک تابع virtual در کلاس والد است و سپس overriding آن در کلاس فرزند در هنگام run time که کاملا سبب hiding تابع اصلی در کلاس والد می شود. ( بکار بردن واژه های کلیدی ذکر شده در آن الزامی است و عمدا متدی را مجازی و سپس overide می کنیم تا .... )

در بحث ارث بری فوق ، تعریف تابعی همنام با تابعی در کلاس والد در کلاس فرزند ، سبب hiding تابع کلاس والد در run time‌ خواهد شد ، مگر ....

و در کل تفاوتی با ارث بری ++ C و غیره ندارد مگر در مورد عدم وجود ارث بری چندگانه که در سی پلاس پلاس وجود دارد و در سی شارپ فقط ارث بری یگانه مطرح شده است ( هر چند با مفهوم اینترفیس ها این بحث را هم می توان کما بیش در سی شارپ پیاده کرد )

Kambiz
چهارشنبه 29 مرداد 1382, 21:47 عصر
ممنون از توضیح کاملی که ارائه فرمودید.
برای اینکه باعث گمراهی دیگران نشومِ٬ با توضیحات شما نتیجه این است که کد دومی که در یادداشت بالا نوشتم متد print مربوط به کلاس Parent را صدا می‌زند.

Vahid_Nasiri
پنج شنبه 30 مرداد 1382, 01:10 صبح
کاملا همینطور است. خروجی



Parent parent = new Child&#40;&#41;;
parent.print&#40;&#41;;

به صورت


Child Constructor.
I'm a Parent Class.

است