Nozioni fondamentali sull'ereditarietà (Visual Basic)

L'istruzione Inherits viene usata per dichiarare una nuova classe, denominata classe derivata, basata su una classe esistente, nota come classe base. Le classi derivate ereditano e possono estendere le proprietà, i metodi, gli eventi, i campi e le costanti definiti nella classe base. La sezione seguente descrive alcune delle regole per l'ereditarietà e i modificatori che è possibile usare per modificare il modo in cui le classi ereditano o vengono ereditate:

  • Per impostazione predefinita, tutte le classi sono ereditabili a meno che non siano contrassegnate con la NotInheritable parola chiave . Le classi possono ereditare da altre classi del progetto o da classi in altri assembly a cui fa riferimento il progetto.

  • A differenza dei linguaggi che consentono l'ereditarietà multipla, Visual Basic consente solo l'ereditarietà singola nelle classi, ovvero le classi derivate possono avere una sola classe base. Anche se l'ereditarietà multipla non è consentita nelle classi, le classi possono implementare più interfacce, che possono eseguire in modo efficace le stesse estremità.

  • Per impedire l'esposizione di elementi con restrizioni in una classe di base, il tipo di accesso di una classe derivata deve essere uguale o più restrittivo rispetto alla relativa classe base. Ad esempio, una Public classe non può ereditare una Friend classe o Private e una Friend classe non può ereditare una Private classe.

Modificatori di ereditarietà

Visual Basic introduce le istruzioni e i modificatori a livello di classe seguenti per supportare l'ereditarietà:

  • Inherits statement : specifica la classe di base.

  • NotInheritable modificatore: impedisce ai programmatori di usare la classe come classe di base.

  • MustInherit modificatore : specifica che la classe è destinata all'uso solo come classe di base. Le istanze delle MustInherit classi non possono essere create direttamente. Possono essere create solo come istanze della classe base di una classe derivata. Altri linguaggi di programmazione, ad esempio C++ e C#, usano il termine classe astratta per descrivere tale classe.

Override di proprietà e metodi nelle classi derivate

Per impostazione predefinita, una classe derivata eredita proprietà e metodi dalla relativa classe di base. Se una proprietà o un metodo ereditato deve comportarsi in modo diverso nella classe derivata, è possibile eseguirne l'override. Ovvero, è possibile definire una nuova implementazione del metodo nella classe derivata. I seguenti modificatori consentono di controllare le modalità di override di proprietà e metodi:

  • Overridable : consente l'override di una proprietà o di un metodo in una classe derivata.

  • Overrides : esegue l'override di una proprietà o di un Overridable metodo definito nella classe di base.

  • NotOverridable : impedisce l'override di una proprietà o di un metodo in una classe che eredita. Per impostazione predefinita, Public i metodi sono NotOverridable.

  • MustOverride : richiede che una classe derivata eseva l'override della proprietà o del metodo. Quando si usa la MustOverride parola chiave , la definizione del metodo è costituita solo dall'istruzione Sub, Functiono Property . Non sono consentite altre istruzioni e in particolare non è presente alcuna End Sub istruzione o End Function . MustOverride i metodi devono essere dichiarati nelle MustInherit classi.

Si supponga di voler definire classi per gestire le retribuzioni. È possibile definire una classe generica Payroll contenente un RunPayroll metodo che calcola le retribuzioni per una settimana tipica. È quindi possibile usare Payroll come classe di base per una classe più specializzata BonusPayroll , che può essere usata durante la distribuzione dei bonus dei dipendenti.

La BonusPayroll classe può ereditare ed eseguire l'override del PayEmployee metodo definito nella classe base Payroll .

L'esempio seguente definisce una classe Payroll, base e una classe derivata , BonusPayroll, che esegue l'override di un metodo ereditato, PayEmployee. Una routine, RunPayroll, crea e quindi passa un Payroll oggetto e un BonusPayroll oggetto a una funzione , Pay, che esegue il PayEmployee metodo di entrambi gli oggetti.

Const BonusRate As Decimal = 1.45D
Const PayRate As Decimal = 14.75D

Class Payroll
    Overridable Function PayEmployee(
        ByVal HoursWorked As Decimal,
        ByVal PayRate As Decimal) As Decimal

        PayEmployee = HoursWorked * PayRate
    End Function
End Class

Class BonusPayroll
    Inherits Payroll
    Overrides Function PayEmployee(
        ByVal HoursWorked As Decimal,
        ByVal PayRate As Decimal) As Decimal

        ' The following code calls the original method in the base 
        ' class, and then modifies the returned value.
        PayEmployee = MyBase.PayEmployee(HoursWorked, PayRate) * BonusRate
    End Function
End Class

Sub RunPayroll()
    Dim PayrollItem As Payroll = New Payroll
    Dim BonusPayrollItem As New BonusPayroll
    Dim HoursWorked As Decimal = 40

    MsgBox("Normal pay is: " &
        PayrollItem.PayEmployee(HoursWorked, PayRate))
    MsgBox("Pay with bonus is: " &
        BonusPayrollItem.PayEmployee(HoursWorked, PayRate))
End Sub

Parola chiave MyBase

La MyBase parola chiave si comporta come una variabile oggetto che fa riferimento alla classe base dell'istanza corrente di una classe. MyBase viene spesso usato per accedere ai membri della classe base sottoposti a override o ombreggiati in una classe derivata. In particolare, MyBase.New viene usato per chiamare in modo esplicito un costruttore di classe base da un costruttore di classe derivata.

Si supponga, ad esempio, di progettare una classe derivata che esegue l'override di un metodo ereditato dalla classe base. Il metodo sottoposto a override può chiamare il metodo nella classe base e modificare il valore restituito, come illustrato nel frammento di codice seguente:

Class DerivedClass
    Inherits BaseClass
    Public Overrides Function CalculateShipping(
        ByVal Dist As Double,
        ByVal Rate As Double) As Double

        ' Call the method in the base class and modify the return value.
        Return MyBase.CalculateShipping(Dist, Rate) * 2
    End Function
End Class

Nell'elenco seguente vengono descritte le restrizioni relative all'uso MyBasedi :

  • MyBase fa riferimento alla classe base immediata e ai relativi membri ereditati. Non può essere utilizzata per accedere Private ai membri della classe .

  • MyBase è una parola chiave, non un oggetto reale. MyBase non può essere assegnato a una variabile, passata alle routine o utilizzata in un Is confronto.

  • Il metodo qualificato MyBase non deve essere definito nella classe base immediata. Può invece essere definito in una classe di base ereditata indirettamente. Affinché un riferimento qualificato da MyBase per la compilazione venga compilato correttamente, alcune classi di base devono contenere un metodo che corrisponde al nome e ai tipi di parametri visualizzati nella chiamata.

  • Non è possibile usare MyBase per chiamare MustOverride i metodi della classe base.

  • MyBase non può essere utilizzato per qualificarsi. Di conseguenza, il codice seguente non è valido:

    MyBase.MyBase.BtnOK_Click()

  • MyBase non può essere usato nei moduli.

  • MyBase non può essere utilizzato per accedere ai membri della classe base contrassegnati come Friend se la classe di base si trovi in un assembly diverso.

Per altre informazioni e un altro esempio, vedere Procedura: Accedere a una variabile nascosta da una classe derivata.

Parola chiave MyClass

La MyClass parola chiave si comporta come una variabile oggetto che fa riferimento all'istanza corrente di una classe come implementato in origine. MyClassMeè simile a , ma ogni chiamata di metodo e proprietà su MyClass viene considerata come se il metodo o la proprietà fosse NotOverridable. Pertanto, il metodo o la proprietà non è interessato dall'override in una classe derivata.

  • MyClass è una parola chiave, non un oggetto reale. MyClass non può essere assegnato a una variabile, passata alle routine o utilizzata in un Is confronto.

  • MyClass fa riferimento alla classe contenitore e ai relativi membri ereditati.

  • MyClass può essere usato come qualificatore per Shared i membri.

  • MyClass non può essere usato all'interno di un Shared metodo, ma può essere usato all'interno di un metodo di istanza per accedere a un membro condiviso di una classe.

  • MyClass non può essere usato nei moduli standard.

  • MyClass può essere usato per qualificare un metodo definito in una classe di base e che non dispone dell'implementazione del metodo fornito in tale classe. Tale riferimento ha lo stesso significato di MyBase.Method.

Nell'esempio seguente vengono confrontati Me e MyClass.

Class baseClass
    Public Overridable Sub testMethod()
        MsgBox("Base class string")
    End Sub
    Public Sub useMe()
        ' The following call uses the calling class's method, even if
        ' that method is an override.
        Me.testMethod()
    End Sub
    Public Sub useMyClass()
        ' The following call uses this instance's method and not any
        ' override.
        MyClass.testMethod()
    End Sub
End Class
Class derivedClass : Inherits baseClass
    Public Overrides Sub testMethod()
        MsgBox("Derived class string")
    End Sub
End Class
Class testClasses
    Sub startHere()
        Dim testObj As derivedClass = New derivedClass()
        ' The following call displays "Derived class string".
        testObj.useMe()
        ' The following call displays "Base class string".
        testObj.useMyClass()
    End Sub
End Class

Anche se derivedClass esegue l'override testMethoddi , la MyClass parola chiave in useMyClass nullifica gli effetti dell'override e il compilatore risolve la chiamata alla versione della classe base di testMethod.

Vedi anche