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

Espressioni di oggetto (F#)

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.