Ereditarietà (C#)
L'ereditarietà viene utilizzata per modellare la relazione di tipo "è", o definizione di sottotipo, nella programmazione orientata a oggetti.
Definizione di relazioni di ereditarietà
È possibile specificare relazioni di ereditarietà utilizzando la parola chiave inherit in una dichiarazione di classe. Nell'esempio seguente viene illustrata la forma sintattica di base.
type MyDerived(...) =
inherit MyBase(...)
Una classe può disporre al massimo di una classe di base diretta. Se non si specifica una classe di base utilizzando la parola chiave inherit, la classe eredita in modo implicito da Object.
Membri ereditati
Se una classe eredita da un'altra classe, i metodi e i membri della classe di base sono disponibili per gli utenti della classe derivata come se fossero membri diretti della classe derivata.
Le associazioni let e i parametri dei costruttori sono privati di una classe e, pertanto, non è possibile accedervi dalle classi derivate.
La parola chiave base è disponibile nelle classi derivate e fa riferimento all'istanza della classe di base. Il suo utilizzo è analogo a quello dell'autoidentificatore.
Metodi virtuali e override
I metodi (e le proprietà) virtuali in F# funzionano in modo in parte diverso rispetto agli altri linguaggi .NET. Per dichiarare un nuovo membro virtuale, si utilizza la parola chiave abstract. Questa modalità viene utilizzata indipendentemente dal fatto che venga fornita un'implementazione predefinita per il metodo. Una definizione completa di un metodo virtuale in una classe di base segue pertanto questo modello:
abstract member method-name : type
default self-identifier.method-name argument-list = method-body
In una classe derivata un override di un metodo virtuale segue invece questo modello:
override self-identifier.method-name argument-list = method-body
Se si omette l'implementazione predefinita nella classe di base, la classe di base diventa una classe astratta.
Nell'esempio di codice seguente viene illustrata la dichiarazione di un nuovo metodo virtuale function1 in una classe di base e viene indicato come eseguire l'override del metodo in una classe derivata.
type MyClassBase1() =
let mutable z = 0
abstract member function1 : int -> int
default u.function1(a : int) = z <- z + a; z
type MyClassDerived1() =
inherit MyClassBase1()
override u.function1(a: int) = a + 1
Costruttori ed ereditarietà
Il costruttore per la classe di base deve essere chiamato nella classe derivata. Gli argomenti per il costruttore della classe di base sono visualizzati nell'elenco di argomenti nella clausola inherit. I valori utilizzati devono essere determinati dagli argomenti forniti al costruttore della classe derivata.
Nel codice seguente vengono illustrate una classe di base e una classe derivata, dove la classe derivata chiama il costruttore della classe di base nella clausola inherit:
type MyClassBase2(x: int) =
let mutable z = x * x
do for i in 1..z do printf "%d " i
type MyClassDerived2(y: int) =
inherit MyClassBase2(y * 2)
do for i in 1..y do printf "%d " i
Nel caso di più costruttori, è possibile utilizzare il codice seguente. La prima riga dei costruttori della classe derivata è la clausola inherit e i campi appaiono come campi espliciti dichiarati con la parola chiave val. Per ulteriori informazioni, vedere Campi espliciti: parola chiave val.
type BaseClass =
val string1 : string
new (str) = { string1 = str }
new () = { string1 = "" }
type DerivedClass =
inherit BaseClass
val string2 : string
new (str1, str2) = { inherit BaseClass(str1); string2 = str2 }
new (str2) = { inherit BaseClass(); string2 = str2 }
let obj1 = DerivedClass("A", "B")
let obj2 = DerivedClass("A")
Alternative all'ereditarietà
Nei casi in cui è necessaria una modifica minore di un tipo, considerare l'utilizzo di un'espressione di oggetto in alternativa all'ereditarietà. Nell'esempio seguente viene illustrato l'utilizzo di un'espressione di oggetto come alternativa alla creazione di un nuovo tipo derivato:
open System
let object1 = { new Object() with
override this.ToString() = "This overrides object.ToString()"
}
printfn "%s" (object1.ToString())
Per ulteriori informazioni sulle espressioni di oggetto, vedere Espressioni di oggetto (F#).
Quando si creano gerarchie di oggetti, considerare l'utilizzo di un'unione discriminata anziché dell'ereditarietà. Le unioni discriminate consentono inoltre di modellare vari comportamenti di oggetti differenti che condividono un tipo complessivo comune. Una singola unione discriminata consente spesso di eliminare la necessità di numerose classi derivate che costituiscono variazioni minori una dell'altra. Per informazioni sulle unioni discriminate, vedere Unioni discriminate (F#).
Vedere anche
Riferimenti
Altre risorse
Riferimenti per il linguaggio F#
Cronologia delle modifiche
Data |
Cronologia |
Motivo |
---|---|---|
Settembre 2010 |
Sono state aggiunte informazioni ed esempi di codice per l'utilizzo di più costruttori della classe base. |
Miglioramento delle informazioni. |