TAHA
03-11-2010, 08:51 PM
.wysiwyg { BACKGROUND: #f5f5ff; FONT: 10pt tahoma,tahoma,tahoma; COLOR: #000000 } P { MARGIN: 0px } .inlineimg { VERTICAL-ALIGN: middle } وراثت چند شکلی
وراثت اجازه میدهد که کلاس جدیدی تعریف کنید که تمام اعضاء و اعمال یک کلاس که قبلا تعریف شده را در خود داشته باشد. به این ترتیب میتوانید کلاسهایی درست کنید که اعمال پایه و مشترکی را انجام دهند و سپس زیر کلاسهای خاصی تولید کنید که خدمات متفاوت اما مرتبطی ارائه دهند.
در این بخش یاد میگیرید که چگونه از وراثت برای مشتق کردن کلاسهای جدید از کلاسهای پایه استفاده کنید، چطور پیاده سازی جدیدی از اعضای یک کلاس پایه انجام دهید و چطور کلاسهای پایه مجرد درست کنید.
وراثت
وراثت این امکان را به شما میدهد که چندین کلاس تولید کنید که از هم متمایزند اما در برخی از اعمال با هم شریکاند. کلاسهای ویژهای که کلاس “مشتق شده ” (Derived Classes) نامیده میشوند، از کلاس مشترک که “کلاس پایه” (Base Class) نامیده میشود ارث میبرند. کلاسDerived را همچنین کلاس تعمیم یافته (Extended) یک کلاس پایه نیز مینامند. کلاس پایه اعمال مشترکی که به هر کلاس مشتق عرضه میشود را کپسوله سازی میکند. برای مثال فرض کنید کلاسی به نام کامیون داریم، کلاس کامیون تمامی اعمال اولیه که یک ماشین نیاز دارد را داراست. متدهایی برای به جلو رفتن، برگشتن و روشن شدن دارد و تمام متدهای لازم برای برای انجام این اعمال را کپسوله میکند. شاید شما یک کلاس مشتق که PickupTruck نام دارد تعریف کنید که از کلاس کامیون ارث میبرد. چون این از کامیون ارث می برد همه اعمال و قابلیتهایی که کامیون تامین میکند را دارد. سپس شما میتوانید قابلیتهای اضافهای را برای کلاس جدید پیاده سازی کنید، مانند خصوصیت “بار”. کلاس PickupTruck میتواند به عنوان یک کلاس پایه برای کلاس مشتق دیگر “کامیون چهار دنده” ایفای نقش کند.
چند رفتاری در کلاسهای وارث
عموما” کلاسهای وارث یک رابطه “یک … است” با کلاس پایه دارند. یک “کامیون کشاورزی چهاردنده” یک “کامیون کشاورزی” است و یک کامیون “کشاورزی” یک “کامیون” است. هر نمونه از کلاس مشتق میتواند رفتار متفاوتی به عنوان نمونهای از کلاس پایهاش داشته باشد. پس، اگر متدی نیاز به شیئ کامیون داشته باشد شما میتوانید شیئ کامیون کشاورزی را عرضه کنید. هر کلاس مشتق ممکن است به طور ضمنی به کلاس پایه خود تبدیل شود. وقتی یک کلاس به کلاس پایه خودش تبدیل میشود، هر عضوی که به وسیله کلاس مشتق پیاده سازی شده غیر قابل دسترس خواهند شد و تنها اعضای کلاس پایه در دسترس خواند بود.
ساختن کلاسهای وارث
یک کلاس وارث به وسیله کلمه کلیدی Inherits در VB.NET تعریف میشود. در مثال زیر کلاس PickupTruckکه از کلاس Truck ارث برده را تعریف نمودیم:
Public Class PickupTruck
Inherits Truck
‘ Additional implementation omitted
End Class
کلاس ها فقط میتوانند از یک کلاس پایه ارث ببرند اما میتوانند چندین اینترفیس را پیاده سازی کنند. اگر کلاس شما چندین اینترفیس را پیاده سازی کند و همچنین از یک کلاس ارث ببرد، باید از کلمه کلیدی Implements را بلافاصله بعد از کلمه کلیدی Inherits استفاده کنید:
Public Class FourWheelDrivePickupTruck
Inherits PickupTruck
Implements IFourWheelDrive
‘ Additional implementation omitted
End Class
وقتی که کلاس وارث تعریف شد، میتوانید اعضای اضافی را پیاده سازی کنید که باعث اضافه شدن اعمال اختیاری به کلاستان میشود.
کلاسهای بدون وارث
گاهی شاید بخواهید کلاسی درست کنید که نتواند به عنوان کلاس پایه برای دیگر کلاسها عمل کند. به عنوان مثال شاید کلاس خاصی تعریف کنید که از آن در کامپوننتهایتان استفاده میکنید و نمیخواهید قابل استفاده به عنوان کلاس پایه برای دیگر برنامه نویسان باشد. در این موارد میتوانید کلاستان را با NotInheritabel برچسب بزنید.
Public NotInheritable Class AClass
‘ Implementation omitted
End Class
اعضاء وارث
وقتی یک کلاس وارث درست میکنیم، کلاس جدید همه اعمال موجود در کلاس پایه را حفظ میکند. علاوه بر این اعضا جدیدی را اضافه میکند، شما میتوانید اعضای وارث را آن طور که میخواهید پیاده سازی کنید. Overriding اعضای پایه این امکان را به شما میدهد که یک عضو موجود در کلاس پایه را پیاده سازی جدیدی کنید. در VB.NET همچنین میتوانید اعضای پایه را سایه بزنید (Shadow). سایه زنی اعضای پایه این امکان را میدهد که عضو پایه را پنهان کنیم و یک عضو جدید با همان نام، اما با خصوصیات کاملا” متفاوت شامل امضاء، و سطح دسترسی جدید اضافه کنیم.
Overriding اعضاء کلاس پایه
وقتی از یک کلاس پایه ارث میبرید، میتوانید پیاده سازی متفاوتی برای اعضای کلاس پایه بوسیله Override کردن آنها داشته باشید. برای مثال، کلاس Car ممکن است متدی با نام GoForward داشته باشد. اگر کلاس SportCar از کلاس Car به ارث ببرد، شاید بخواهد پیاده سازی متفاوتی از متد GoForward داشته باشد. فقط متدها و خصوصیات کلاس پایه میتوانند Override شوند. متغییرها و رویدادهای اعضاء نمیتوانند Override شوند.
با استفاده از کلمه کلیدی Overrides میتوانید پیاده سازی متفاوتی از یک عضو ارایه کنید. پیاده سازی جدید باید امضا و نوع برگشتی یکسانی با عضوی که Override میشود داشته باشد و باید سطح دسترسی مشابهی هم داشته باشد.
‘ This example assumes the existence of a GoForward method in the base class
Public Class SportsCar
Inherits Car
‘ This line declares the overridden method
Public Overrides Sub GoForward(ByVal Speed As Integer)
‘ Implementation omitted
End Sub
End Class
وقتی که یک عضو Override میشود، عضو جدید “جایگزین عضو کلاس پایه” نامیده میشود. به عنوان مثال، اگر نمونهای از یک کلاس وارث از کلاس پایه خودش ساخته شود و یک متد Override شده فراخوانی شود، پیاده سازی جدید اجرا خواهد شد. برای Override عضو کلاس پایه، اعضا باید با Overridable برچسب زده شوند:
Public Overridable Sub OverrideMe()
‘ Implementation omitted
End Sub
سایه زنی (Shadowing) اعضای کلاس پایه
در بخش قبل آموختید که چطور پیاده سازی عضوی در کلاس پایه را با پیاده سازی متفاوتی از عضو مشابهی، جایگزین کنید. در NET. همچنین امکان پذیر است که پیاده سازی عضو کلاس پایه را پنهان کرد و با عضو کاملا” جدیدی جایگزین کرد، که سطح دسترسی و امضای متفاوتی داشته باشد یا حتی نوع متفاوتی داشته باشد. این کار Shadowing نامیده میشود. در VB.NET از کلمه کلیدی Shadows برای جایگزینی پیاده سازی جدید برای عضو کلاس پایه استفاده میکنیم.
‘ This is the base class
Public Class MyBaseClass
Public Function MyMethod(ByVal I As Integer) As String
‘ Implementation omitted
End Function
End Class
‘ This class inherits the base class
Public Class MyInheritedClass
Inherits MyBaseClass
‘ This function shadows the MyMethod sub defined in the base class.
‘ Note that this member has a completely different signature, access
‘ level and returns a different type of value.
Friend Shadows Function MyMethod(ByVal S As String) As Integer
‘ Implementation omitted
End Function
End Class
حفظ سازگاری با اعضای سایه زده شده
وقتی عضو کلاسی را سایه میزنید یا پنهان میکنید، پیاده سازی کلاس پایه را پنهان میکنید و پیاده سازی جدیدی میسازید که نیاز به مشخصات مشابه با عضو کلاس پایه ندارد. این میتواند موجب مشکلاتی شود. اگر شیئی تابع MyMethod را از مثال قبل صدا بزند، این انتظار دارد که نوع String برگشت داده شود و وقتی یک Interger از نمونه عضو سایه زده شده برمیگردد، یک خطا ایجاد میشود. بنابراین باید وقتی عضوی را سایه میزنید یا پنهان میکنید دقت زیادی داشته باشید. این باید در مواردی انجام شود که شما یقین دارید که سازگاری از بین نمیرود.
‘ This example uses the MyBaseClass and MyInheritedClass classes
‘ defined in the previous code example.
Dim X As New MyInheritedClass()
Dim Y As MyBaseClass
‘ X and Y now refer to the same object, but the variables have
‘ different types.
Y = X
‘ Because the variable X is of the MyInheritedClass type, the new
‘ member will be called by this line.
X.MyMethod(“A String”)
‘ However, because the variable Y is of the MyBaseClass type, the
‘ original implementation of the member will be called by this line.
Y.MyMethod(42)
دسترسی به اعضاء کلاس پایه
وقتی اعضاء را Override یا پنهان میسازید، شاید بخواهید به پیاده سازی اعضاء در کلاس پایه دسترسی داشته باشید. بوسیله کلمه کلیدی MyBase میتوانید به اعضای کلاس پایه دسترسی داشته باشید. این کلمه اشارهای به پیاده سازی کلاس پایه دارد و اجازه میدهد که پیاده سازی اعضای کلاس پایه را در اختیار داشته باشید. مثال زیر نشان میدهد که چگونه یک عضو کلاس پایه احضار میشود:
‘ This example demonstrates calling the base class implementation of
‘ MyMethod from within an override of that method
Public Overrides Function MyMethod(ByVal I As Integer) As String
MyBase.MyMethod(I)
‘ Additional implementation omitted
End Function
اعضاء حفاظت شده (Protected Members)
حال یک مرور سربع بر سطوح دسترسی خواهیم داشت. اعضاء Public در دسترس همه بخشهای یک برنامه هستند) شامل کلاسهای خارجی(. اعضاء Friend یاInternal برای اعضای اسمبلی محلی (Local Assembly) در دسترس اما برای فراخوانیهای خارجی قابل دسترسی نیستند. اعضاء Private فقط درون کلاس خودشان قابل دسترساند و نمیتوانند مورد استفاده هیچ فراخوان دیگری (شامل کلاسهای وارث) قرار بگیرند. دو سطح دسترسی دیگر Protected و Protected Frind هستند.
وقتی کلمه کلیدی Protectded با یک عضو کلاس استفاده میشود، آن عضو برای فراخوانیهای خارجی، سطح دسترسی مشابهی با کلمه کلیدی Private دارد. تفاوتشان در این است که اعضای Protected برای کلاسهای مشتق شده هم قابل دسترسی هستند. مثال زیر را ملاحظه کنید:
‘The base class defines two methods: a private method and a protected
‘ method.
Public Class BaseClass
‘ A private method cannot be called from derived classes
Private Sub Method1()
‘ Implementation omitted
End Sub
‘ A protected member can be called from derived classes
Protected Sub Method2()
‘ Implementation omitted
End Sub
End Class
‘ The inherited class inherits from BaseClass
Public Class InheritedClass
Inherits BaseClass
Public Sub Demo()
‘ This call is legal because the protected access level allows
‘ access to the member defined by the BaseClass
Me.Method2()
‘ This call will not compile because it attempts to access a
‘ private member of the base class.
Me.Method1()
End Sub
End Class
مثال قبل تفاوت بین اعضاء Private و اعضاء Protected را نشان میدهد. متد Demo قصد دارد که از نمونهای از کلاس وارث Me، با فراخوانی Method1 و Method2 استفاده کند. چون هر دوی این متدها در کلاس پایه تعریف شدهاند، سطح دسترسی آنها تعیین شده، به هر حال آنها میتوانند از کلاس وارث فراخوانده شوند. فراخوانی Method2 موفقیت آمیز است اما از آنجاییکه Method1 خصوصی (Private) است، برای کلاسهای وارث در دسترس نیست.
دومین سطح دسترسی Protect Friend است. این مورد ترکیبی از سطوح Protected و Friend است. بنابراین عضوی که Protect Friend است میتواند بوسیله کلاسهای درون اسمبلی یا کلاسهایی که از آن کلاس ارث میبرند استفاده شوند، به علاوه از درون کلاس خودش هم دردسترس است.
کلاسها و اعضای مجرد
وقتی کامپوننتهایی را میسازید، شاید بخواهید کلاس پایهای درست کنید که برخی اعمال ثابت را داشته باشد اما پیاده سازی دیگر اعضای آن را به کلاسهایی که از آن به ارث میبرند واگذار کنید. شما میتوانید با استفاده از کلاسهای مجرد Abstract Classes این کار را انجام دهید، کلاسهایی که باید به ارث رسیده شوند.
کلاسهای مجرد شبیه اینترفیسها هستند، اما امکانات زیاد مشترکی با کلاسها دارند. یک کلاس مجرد نمیتواند خودش را مقداردهی کند، او باید اول ارث برده شود. کلاس مجرد میتواند همه یا مقداری از پیاده سازی یک کلاس واقعی را تامین کند و یا حتی هیچ پیاده سازیی از یک کلاس واقعی را ارائه نکند. آنها مانند اینترفیسها میتوانند اعضایی که باید درون کلاس وارث پیاده سازی شوند را تعیین کند. بر خلاف اینترفیسها یک کلاس، تنها میتواند از یک کلاس مجرد به ارث ببرد. مانند کلاسها، کلاسهای مجرد میتوانند پیاده سازی کاملی از اعضا را تامین کنند، اما همچنین برخلاف کلاسها، کلاسهای مجرد میتوانند اعضایی که باید توسط کلاسهای وارث پیاده سازی شوند را تعیین کنند.
ساختن کلاسهای مجرد (Abstract Classes)
بوسیله کلمه کلیدی MustInherit میتوانید کلاسی را کلاس مجرد کنید.
Public MustInherit Class AbstractClass
‘ Implementation omitted
End Class
تعریف اعضای مجرد
مانند کلاس معمولی، کلاس مجرد میتواند هر عضوی را پیاده سازی کند. اعضای معمولی یک کلاس مجرد میتواند Overridable (مجازی) شود، در این مورد کلاسهای وارث میتوانند اعضایی که نیاز دارند را بسازند، یا میتوانند غیر مجازی شوند و بنابراین پیاده سازی ثابتی دارند که میتواند با همه اعضاء مشترک شود.
کلاسهای مجرد هم میتواند اعضای مجرد تعیین کند. اعلان یک عضو مجرد بسیار شبیه اعلان یک عضو اینترفیس است. تنها نوع عضو، سطح دسترسی، پارامترهای مورد نیاز و نوعی که برگرداننده میشود تعیین میشود. هیچ جزییاتی راجع به پیاده سازی اعضایی که در متد اعلان شدهاند وجود ندارد. پس، فقط اعضاء اینترفیس تعیین میشوند. برای اعلان یک عضو مجرد، باید از کلمه کلیدی MustOverride استفاده کرد. اعضا مجرد باید درکلاسهای مجرد اعلان شوند. اگر سعی کنید عضو مجردی را در کلاس غیر مجردی اعلان کنید، کامپایلر خطایی اعلام خواهد کرد. مثال بفدی کلاس مجردی با ۳ عضو مجرد نشان می دهد:
Public MustInherit Class Car
Public MustOverride Sub GoForward(ByVal i As Integer)
Public MustOverride Function CheckSpeed() As Integer
Public MustOverride Property Color() As String
End Class
ارث بری از یک کلاس مجرد
وقتی یک کلاس غیر مجرد از یک کلاس مجرد ارث میبرد، باید پیاده سازی برای هر یک از اعضا مجرد تعیین شده بوسیله کلاس مجرد تامین کند. مثال بعدی پیاده سازی از کلاس مجرد مثال قبلی را نشان میدهد.
Public Class MyCar
Inherits Car
Public Overrides Sub GoForward(ByVal I As Integer)
‘ Specific implementation of this method would go here
End Sub
Public Overrides Function CheckSpeed() As Integer
‘ Implementation for this method goes here
End Function
Public Overrides Property Color() As String
Get
‘ Both the getter and the setter must be implemented
End Get
Set(ByVal Value As String)
‘ Setter implementation goes here
End Set
End Property
End Class
همچنین میتوانید کلاس مجرد جدیدی را با ارث بری از کلاس مجرد حاضری درست کنید. در این مورد، کلاس مجرد مشتق شده نیاز ندارد که پیاده سازیی برای اعضا مجرد تعیین شده در کلاس پایه تعریف کند. اما اگر نیاز باشد میتوان این اعضاء را نیز مجددا پیاده سازی کند.
وراثت اجازه میدهد که کلاس جدیدی تعریف کنید که تمام اعضاء و اعمال یک کلاس که قبلا تعریف شده را در خود داشته باشد. به این ترتیب میتوانید کلاسهایی درست کنید که اعمال پایه و مشترکی را انجام دهند و سپس زیر کلاسهای خاصی تولید کنید که خدمات متفاوت اما مرتبطی ارائه دهند.
در این بخش یاد میگیرید که چگونه از وراثت برای مشتق کردن کلاسهای جدید از کلاسهای پایه استفاده کنید، چطور پیاده سازی جدیدی از اعضای یک کلاس پایه انجام دهید و چطور کلاسهای پایه مجرد درست کنید.
وراثت
وراثت این امکان را به شما میدهد که چندین کلاس تولید کنید که از هم متمایزند اما در برخی از اعمال با هم شریکاند. کلاسهای ویژهای که کلاس “مشتق شده ” (Derived Classes) نامیده میشوند، از کلاس مشترک که “کلاس پایه” (Base Class) نامیده میشود ارث میبرند. کلاسDerived را همچنین کلاس تعمیم یافته (Extended) یک کلاس پایه نیز مینامند. کلاس پایه اعمال مشترکی که به هر کلاس مشتق عرضه میشود را کپسوله سازی میکند. برای مثال فرض کنید کلاسی به نام کامیون داریم، کلاس کامیون تمامی اعمال اولیه که یک ماشین نیاز دارد را داراست. متدهایی برای به جلو رفتن، برگشتن و روشن شدن دارد و تمام متدهای لازم برای برای انجام این اعمال را کپسوله میکند. شاید شما یک کلاس مشتق که PickupTruck نام دارد تعریف کنید که از کلاس کامیون ارث میبرد. چون این از کامیون ارث می برد همه اعمال و قابلیتهایی که کامیون تامین میکند را دارد. سپس شما میتوانید قابلیتهای اضافهای را برای کلاس جدید پیاده سازی کنید، مانند خصوصیت “بار”. کلاس PickupTruck میتواند به عنوان یک کلاس پایه برای کلاس مشتق دیگر “کامیون چهار دنده” ایفای نقش کند.
چند رفتاری در کلاسهای وارث
عموما” کلاسهای وارث یک رابطه “یک … است” با کلاس پایه دارند. یک “کامیون کشاورزی چهاردنده” یک “کامیون کشاورزی” است و یک کامیون “کشاورزی” یک “کامیون” است. هر نمونه از کلاس مشتق میتواند رفتار متفاوتی به عنوان نمونهای از کلاس پایهاش داشته باشد. پس، اگر متدی نیاز به شیئ کامیون داشته باشد شما میتوانید شیئ کامیون کشاورزی را عرضه کنید. هر کلاس مشتق ممکن است به طور ضمنی به کلاس پایه خود تبدیل شود. وقتی یک کلاس به کلاس پایه خودش تبدیل میشود، هر عضوی که به وسیله کلاس مشتق پیاده سازی شده غیر قابل دسترس خواهند شد و تنها اعضای کلاس پایه در دسترس خواند بود.
ساختن کلاسهای وارث
یک کلاس وارث به وسیله کلمه کلیدی Inherits در VB.NET تعریف میشود. در مثال زیر کلاس PickupTruckکه از کلاس Truck ارث برده را تعریف نمودیم:
Public Class PickupTruck
Inherits Truck
‘ Additional implementation omitted
End Class
کلاس ها فقط میتوانند از یک کلاس پایه ارث ببرند اما میتوانند چندین اینترفیس را پیاده سازی کنند. اگر کلاس شما چندین اینترفیس را پیاده سازی کند و همچنین از یک کلاس ارث ببرد، باید از کلمه کلیدی Implements را بلافاصله بعد از کلمه کلیدی Inherits استفاده کنید:
Public Class FourWheelDrivePickupTruck
Inherits PickupTruck
Implements IFourWheelDrive
‘ Additional implementation omitted
End Class
وقتی که کلاس وارث تعریف شد، میتوانید اعضای اضافی را پیاده سازی کنید که باعث اضافه شدن اعمال اختیاری به کلاستان میشود.
کلاسهای بدون وارث
گاهی شاید بخواهید کلاسی درست کنید که نتواند به عنوان کلاس پایه برای دیگر کلاسها عمل کند. به عنوان مثال شاید کلاس خاصی تعریف کنید که از آن در کامپوننتهایتان استفاده میکنید و نمیخواهید قابل استفاده به عنوان کلاس پایه برای دیگر برنامه نویسان باشد. در این موارد میتوانید کلاستان را با NotInheritabel برچسب بزنید.
Public NotInheritable Class AClass
‘ Implementation omitted
End Class
اعضاء وارث
وقتی یک کلاس وارث درست میکنیم، کلاس جدید همه اعمال موجود در کلاس پایه را حفظ میکند. علاوه بر این اعضا جدیدی را اضافه میکند، شما میتوانید اعضای وارث را آن طور که میخواهید پیاده سازی کنید. Overriding اعضای پایه این امکان را به شما میدهد که یک عضو موجود در کلاس پایه را پیاده سازی جدیدی کنید. در VB.NET همچنین میتوانید اعضای پایه را سایه بزنید (Shadow). سایه زنی اعضای پایه این امکان را میدهد که عضو پایه را پنهان کنیم و یک عضو جدید با همان نام، اما با خصوصیات کاملا” متفاوت شامل امضاء، و سطح دسترسی جدید اضافه کنیم.
Overriding اعضاء کلاس پایه
وقتی از یک کلاس پایه ارث میبرید، میتوانید پیاده سازی متفاوتی برای اعضای کلاس پایه بوسیله Override کردن آنها داشته باشید. برای مثال، کلاس Car ممکن است متدی با نام GoForward داشته باشد. اگر کلاس SportCar از کلاس Car به ارث ببرد، شاید بخواهد پیاده سازی متفاوتی از متد GoForward داشته باشد. فقط متدها و خصوصیات کلاس پایه میتوانند Override شوند. متغییرها و رویدادهای اعضاء نمیتوانند Override شوند.
با استفاده از کلمه کلیدی Overrides میتوانید پیاده سازی متفاوتی از یک عضو ارایه کنید. پیاده سازی جدید باید امضا و نوع برگشتی یکسانی با عضوی که Override میشود داشته باشد و باید سطح دسترسی مشابهی هم داشته باشد.
‘ This example assumes the existence of a GoForward method in the base class
Public Class SportsCar
Inherits Car
‘ This line declares the overridden method
Public Overrides Sub GoForward(ByVal Speed As Integer)
‘ Implementation omitted
End Sub
End Class
وقتی که یک عضو Override میشود، عضو جدید “جایگزین عضو کلاس پایه” نامیده میشود. به عنوان مثال، اگر نمونهای از یک کلاس وارث از کلاس پایه خودش ساخته شود و یک متد Override شده فراخوانی شود، پیاده سازی جدید اجرا خواهد شد. برای Override عضو کلاس پایه، اعضا باید با Overridable برچسب زده شوند:
Public Overridable Sub OverrideMe()
‘ Implementation omitted
End Sub
سایه زنی (Shadowing) اعضای کلاس پایه
در بخش قبل آموختید که چطور پیاده سازی عضوی در کلاس پایه را با پیاده سازی متفاوتی از عضو مشابهی، جایگزین کنید. در NET. همچنین امکان پذیر است که پیاده سازی عضو کلاس پایه را پنهان کرد و با عضو کاملا” جدیدی جایگزین کرد، که سطح دسترسی و امضای متفاوتی داشته باشد یا حتی نوع متفاوتی داشته باشد. این کار Shadowing نامیده میشود. در VB.NET از کلمه کلیدی Shadows برای جایگزینی پیاده سازی جدید برای عضو کلاس پایه استفاده میکنیم.
‘ This is the base class
Public Class MyBaseClass
Public Function MyMethod(ByVal I As Integer) As String
‘ Implementation omitted
End Function
End Class
‘ This class inherits the base class
Public Class MyInheritedClass
Inherits MyBaseClass
‘ This function shadows the MyMethod sub defined in the base class.
‘ Note that this member has a completely different signature, access
‘ level and returns a different type of value.
Friend Shadows Function MyMethod(ByVal S As String) As Integer
‘ Implementation omitted
End Function
End Class
حفظ سازگاری با اعضای سایه زده شده
وقتی عضو کلاسی را سایه میزنید یا پنهان میکنید، پیاده سازی کلاس پایه را پنهان میکنید و پیاده سازی جدیدی میسازید که نیاز به مشخصات مشابه با عضو کلاس پایه ندارد. این میتواند موجب مشکلاتی شود. اگر شیئی تابع MyMethod را از مثال قبل صدا بزند، این انتظار دارد که نوع String برگشت داده شود و وقتی یک Interger از نمونه عضو سایه زده شده برمیگردد، یک خطا ایجاد میشود. بنابراین باید وقتی عضوی را سایه میزنید یا پنهان میکنید دقت زیادی داشته باشید. این باید در مواردی انجام شود که شما یقین دارید که سازگاری از بین نمیرود.
‘ This example uses the MyBaseClass and MyInheritedClass classes
‘ defined in the previous code example.
Dim X As New MyInheritedClass()
Dim Y As MyBaseClass
‘ X and Y now refer to the same object, but the variables have
‘ different types.
Y = X
‘ Because the variable X is of the MyInheritedClass type, the new
‘ member will be called by this line.
X.MyMethod(“A String”)
‘ However, because the variable Y is of the MyBaseClass type, the
‘ original implementation of the member will be called by this line.
Y.MyMethod(42)
دسترسی به اعضاء کلاس پایه
وقتی اعضاء را Override یا پنهان میسازید، شاید بخواهید به پیاده سازی اعضاء در کلاس پایه دسترسی داشته باشید. بوسیله کلمه کلیدی MyBase میتوانید به اعضای کلاس پایه دسترسی داشته باشید. این کلمه اشارهای به پیاده سازی کلاس پایه دارد و اجازه میدهد که پیاده سازی اعضای کلاس پایه را در اختیار داشته باشید. مثال زیر نشان میدهد که چگونه یک عضو کلاس پایه احضار میشود:
‘ This example demonstrates calling the base class implementation of
‘ MyMethod from within an override of that method
Public Overrides Function MyMethod(ByVal I As Integer) As String
MyBase.MyMethod(I)
‘ Additional implementation omitted
End Function
اعضاء حفاظت شده (Protected Members)
حال یک مرور سربع بر سطوح دسترسی خواهیم داشت. اعضاء Public در دسترس همه بخشهای یک برنامه هستند) شامل کلاسهای خارجی(. اعضاء Friend یاInternal برای اعضای اسمبلی محلی (Local Assembly) در دسترس اما برای فراخوانیهای خارجی قابل دسترسی نیستند. اعضاء Private فقط درون کلاس خودشان قابل دسترساند و نمیتوانند مورد استفاده هیچ فراخوان دیگری (شامل کلاسهای وارث) قرار بگیرند. دو سطح دسترسی دیگر Protected و Protected Frind هستند.
وقتی کلمه کلیدی Protectded با یک عضو کلاس استفاده میشود، آن عضو برای فراخوانیهای خارجی، سطح دسترسی مشابهی با کلمه کلیدی Private دارد. تفاوتشان در این است که اعضای Protected برای کلاسهای مشتق شده هم قابل دسترسی هستند. مثال زیر را ملاحظه کنید:
‘The base class defines two methods: a private method and a protected
‘ method.
Public Class BaseClass
‘ A private method cannot be called from derived classes
Private Sub Method1()
‘ Implementation omitted
End Sub
‘ A protected member can be called from derived classes
Protected Sub Method2()
‘ Implementation omitted
End Sub
End Class
‘ The inherited class inherits from BaseClass
Public Class InheritedClass
Inherits BaseClass
Public Sub Demo()
‘ This call is legal because the protected access level allows
‘ access to the member defined by the BaseClass
Me.Method2()
‘ This call will not compile because it attempts to access a
‘ private member of the base class.
Me.Method1()
End Sub
End Class
مثال قبل تفاوت بین اعضاء Private و اعضاء Protected را نشان میدهد. متد Demo قصد دارد که از نمونهای از کلاس وارث Me، با فراخوانی Method1 و Method2 استفاده کند. چون هر دوی این متدها در کلاس پایه تعریف شدهاند، سطح دسترسی آنها تعیین شده، به هر حال آنها میتوانند از کلاس وارث فراخوانده شوند. فراخوانی Method2 موفقیت آمیز است اما از آنجاییکه Method1 خصوصی (Private) است، برای کلاسهای وارث در دسترس نیست.
دومین سطح دسترسی Protect Friend است. این مورد ترکیبی از سطوح Protected و Friend است. بنابراین عضوی که Protect Friend است میتواند بوسیله کلاسهای درون اسمبلی یا کلاسهایی که از آن کلاس ارث میبرند استفاده شوند، به علاوه از درون کلاس خودش هم دردسترس است.
کلاسها و اعضای مجرد
وقتی کامپوننتهایی را میسازید، شاید بخواهید کلاس پایهای درست کنید که برخی اعمال ثابت را داشته باشد اما پیاده سازی دیگر اعضای آن را به کلاسهایی که از آن به ارث میبرند واگذار کنید. شما میتوانید با استفاده از کلاسهای مجرد Abstract Classes این کار را انجام دهید، کلاسهایی که باید به ارث رسیده شوند.
کلاسهای مجرد شبیه اینترفیسها هستند، اما امکانات زیاد مشترکی با کلاسها دارند. یک کلاس مجرد نمیتواند خودش را مقداردهی کند، او باید اول ارث برده شود. کلاس مجرد میتواند همه یا مقداری از پیاده سازی یک کلاس واقعی را تامین کند و یا حتی هیچ پیاده سازیی از یک کلاس واقعی را ارائه نکند. آنها مانند اینترفیسها میتوانند اعضایی که باید درون کلاس وارث پیاده سازی شوند را تعیین کند. بر خلاف اینترفیسها یک کلاس، تنها میتواند از یک کلاس مجرد به ارث ببرد. مانند کلاسها، کلاسهای مجرد میتوانند پیاده سازی کاملی از اعضا را تامین کنند، اما همچنین برخلاف کلاسها، کلاسهای مجرد میتوانند اعضایی که باید توسط کلاسهای وارث پیاده سازی شوند را تعیین کنند.
ساختن کلاسهای مجرد (Abstract Classes)
بوسیله کلمه کلیدی MustInherit میتوانید کلاسی را کلاس مجرد کنید.
Public MustInherit Class AbstractClass
‘ Implementation omitted
End Class
تعریف اعضای مجرد
مانند کلاس معمولی، کلاس مجرد میتواند هر عضوی را پیاده سازی کند. اعضای معمولی یک کلاس مجرد میتواند Overridable (مجازی) شود، در این مورد کلاسهای وارث میتوانند اعضایی که نیاز دارند را بسازند، یا میتوانند غیر مجازی شوند و بنابراین پیاده سازی ثابتی دارند که میتواند با همه اعضاء مشترک شود.
کلاسهای مجرد هم میتواند اعضای مجرد تعیین کند. اعلان یک عضو مجرد بسیار شبیه اعلان یک عضو اینترفیس است. تنها نوع عضو، سطح دسترسی، پارامترهای مورد نیاز و نوعی که برگرداننده میشود تعیین میشود. هیچ جزییاتی راجع به پیاده سازی اعضایی که در متد اعلان شدهاند وجود ندارد. پس، فقط اعضاء اینترفیس تعیین میشوند. برای اعلان یک عضو مجرد، باید از کلمه کلیدی MustOverride استفاده کرد. اعضا مجرد باید درکلاسهای مجرد اعلان شوند. اگر سعی کنید عضو مجردی را در کلاس غیر مجردی اعلان کنید، کامپایلر خطایی اعلام خواهد کرد. مثال بفدی کلاس مجردی با ۳ عضو مجرد نشان می دهد:
Public MustInherit Class Car
Public MustOverride Sub GoForward(ByVal i As Integer)
Public MustOverride Function CheckSpeed() As Integer
Public MustOverride Property Color() As String
End Class
ارث بری از یک کلاس مجرد
وقتی یک کلاس غیر مجرد از یک کلاس مجرد ارث میبرد، باید پیاده سازی برای هر یک از اعضا مجرد تعیین شده بوسیله کلاس مجرد تامین کند. مثال بعدی پیاده سازی از کلاس مجرد مثال قبلی را نشان میدهد.
Public Class MyCar
Inherits Car
Public Overrides Sub GoForward(ByVal I As Integer)
‘ Specific implementation of this method would go here
End Sub
Public Overrides Function CheckSpeed() As Integer
‘ Implementation for this method goes here
End Function
Public Overrides Property Color() As String
Get
‘ Both the getter and the setter must be implemented
End Get
Set(ByVal Value As String)
‘ Setter implementation goes here
End Set
End Property
End Class
همچنین میتوانید کلاس مجرد جدیدی را با ارث بری از کلاس مجرد حاضری درست کنید. در این مورد، کلاس مجرد مشتق شده نیاز ندارد که پیاده سازیی برای اعضا مجرد تعیین شده در کلاس پایه تعریف کند. اما اگر نیاز باشد میتوان این اعضاء را نیز مجددا پیاده سازی کند.