- Позволение за наследяване
Има две ключови думи, които влияят върху възможността за
наследяване:
NotInheritable
Когато се употребява за дефиниране на клас:
Public NotInheritable Class
InterfaceExample
класът не може да бъде използван като базов.
MustInherit
Когато се употребява за дефиниране на клас:
Public MustInherit Class
InterfaceExample
обектите на този клас не могат да се създадат директно.
Обектите от наследяващите класове могат да се създават, с други думи, MustInherit класове могат да се
използват само (only) като базови
класове.
- Overriding - предефиниране
Има няколко ключови думи, които контролират дали
произхождащият клас ще може да предефинира ( "override")
изпълнението в базовия клас:
Overridable
Позволява,
но не изисква съответния член да бъде предефиниран "overridden". По подразбиране за членове Public e NotOverridable.
Пример:
Public Overridable Sub IncZaplata( )
NotOverridable
Забранява предефиниране (overriding) на членове. По подразбиране за Public членове на класа.
MustOverride
Трябва да
бъде предефиниран (overridden). Когато се
използва тази
ключова дума, дефиницията на члена се ограничава само до деклариращ
ред, без изпълнение и без End Sub или End Function ред. Например:
Public MustOverride Sub IncZaplata(
)
Отбележете,че когато клас модулът съдържа член MustOverride, след това самият клас трябва да
се декларира като MustInherit.
Overrides
Противно на другите модификации, този модификатор принадлежи на
произхождащия клас и индицира, че модифицирания член е
предефинирания (overriding) член на базовия клас. Примерно:
Overrides Sub IncZaplata( )
- Правила за наследяване
В много обектно-ориентирани езици, като C++, класът може да наследява директно
от повече от един базов клас. Нарича се multiple inheritance . VB .NET не поддържа
мултинаследяемост. Не се разрешава такъв код:
' Director Class
Public Class CDirector 'INVALID
Inherits CSlujasht
Inherits CWorker
. . .
End Class
От друга страна, Class C може да наследява от Class B, който може
да наследява от Class A, което оформя йерархия на наследяемост.
Класът може да изпълнява мултиинтерфейси чрез ключова дума Interface.
- MyBase, MyClass, Me
Ключова дума MyBase обезпечава връзка с базовия клас отвътре
произхождащия клас. Ако искате да извикате член на базовия клас отвътре
произхождащия клас може така:
MyBase.MemberName
където MemberName е името на члена. Това ще разреши много неясноти, ако наследяващият клас има
член със същото име. Ключова дума MyBase може да бъде използвана за извикване на конструктора на базовия
клас в ред на инстанциране на член от този клас, така:
MyBase.New(...)
Отбележете, че MyBase не може да бъде използван за викане на членове на Private клас.
Visual Basic търси най-непосредствената версия в родителския клас за
процедурата в заявка. Така че, ако Class C произлиза от Class B, който произлиза от Class A, извикването в Class C към:
MyBase.AProc
първо поглежда в Class B за съответна процедура с име AProc. Ако не я намери, след това VB търси в Class A за съответна процедура. (Под съответствие -matching,
разбираме метод със същата
аргументна сигнатура.) Ключовата дума MyClass обезпечава връзка с клас,
в който ключовата дума се използва. Подобно на ключовата дума Me, с
изключение когато се използва
за викане на метод. За да илюстрираме разликата, нека да вземем клас с
име Class1 и произхождащия клас с име Class1Derived. Всеки клас има метод IncZaplata:
Public Class Class1
Public Overridable Function IncZaplata(ByVal sZaplata As
Single) As Single
IncZaplata = sZaplata *
CSng(1.1)
End Function
Public Sub ShowIncZaplata(ByVal
sZaplata As Single)
MsgBox(Me.IncZaplata(sZaplata))
MsgBox(MyClass.IncZaplata(sZaplata))
End Sub
End Class
Public Class Class1Derived
Inherits Class1
Public Overrides Function IncZaplata(ByVal sZaplata As
Single) As Single
IncZaplata = sZaplata *
CSng(1.2)
End Function
End Class
Сега нека вземем следния код, поставен в модула на формата:
Dim c1 As New Class1( )
Dim c2 As New
Class1Derived( )
Dim c1var As Class1
c1var = c1
c1var.IncZaplata(1000) ' дава 1100, 1100
c1var = c2
c1var.IncZaplata(1000) ' дава 1200, 1100
Първото извикване на IncZaplata е
направено използвайки променлива от тип Class1, която свързва с обект от тип Class1. В този случай и двете
повиквания:
Me.IncZaplata
MyClass.IncZaplata
връщат същата стойност, защото викат IncZaplata от базовия клас Class1.
Докато във втория случай, променливата от тип Class1 държи връзка към обект от
произхождащия клас, Class1Derived.
В този случай, Me свързва към обект от тип Class1Derived, докато MyClass все още свързва към базовия клас Class1 където се появява ключовата дума MyClass. Tака,
Me.IncZaplata
връща 1200 докато:
MyClass.IncZaplata
връща 1100.