Interfacce (F#)

Le interfacce specificano set di membri correlati implementati da altre classi.

// Interface declaration:
[ attributes ]
type interface-name =
   [ interface ]
     [ inherit base-interface-name ...]
     abstract member1 : [ argument-types1 -> ] return-type1
     abstract member2 : [ argument-types2 -> ] return-type2
     ...
   [ end ]

// Implementing, inside a class type definition:
interface interface-name with
   member self-identifier.member1 argument-list = method-body1
   member self-identifier.member2 argument-list = method-body2

// Implementing, by using an object expression:
[ attributes ]
let class-name (argument-list) =
   { new interface-name with
       member self-identifier.member1 argument-list = method-body1
       member self-identifier.member2 argument-list = method-body2
       [ base-interface-definitions ]
   }
   member-list

Note

Le dichiarazioni di interfaccia assomigliano a dichiarazioni di classe ad eccezione del fatto che non vengono implementati membri. Tutti i membri sono invece astratti, come indicato dalla parola chiave abstract. Per i metodi astratti non viene fornito un corpo del metodo. È tuttavia possibile fornire un'implementazione predefinita includendo anche una definizione separata del membro come un metodo insieme alla parola chiave default. Questa operazione equivale alla creazione di un metodo virtuale in una classe di base negli altri linguaggi .NET. Per tale metodo virtuale è possibile eseguire l'override nelle classi che implementano l'interfaccia.

Vi sono due metodi per implementare le interfacce: tramite espressioni dell'oggetto e tramite tipi di classe. In entrambi i casi, il tipo di classe o l'espressione dell'oggetto fornisce corpi del metodo per metodi astratti dell'interfaccia. Le implementazioni sono specifiche di ogni tipo che implementa l'interfaccia. I metodi di interfaccia in tipi diversi potrebbero pertanto essere diversi l'uno dall'altro.

Le parole chiave interface e end, che contrassegnano l'inizio e la fine della definizione, sono facoltative quando si utilizza la sintassi leggera. Se non si utilizzano queste parole chiave, il compilatore tenta di determinare tramite inferenza se il tipo è una classe o un'interfaccia, analizzando i costrutti utilizzati. Se si definisce un membro o si utilizza altra sintassi delle classi, il tipo viene interpretato come classe.

Lo stile di codifica .NET prevede che tutte le interfacce inizino con una I maiuscola.

Implementazione delle interfacce tramite tipi di classe

È possibile implementare una o più interfacce in un tipo di classe utilizzando la parola chiave interface, il nome dell'interfaccia e la parola chiave with, seguita dalle definizioni di membro dell'interfaccia, come illustrato nel codice seguente.

type IPrintable =
   abstract member Print : unit -> unit

type SomeClass1(x: int, y: float) =
   interface IPrintable with
      member this.Print() = printfn "%d %f" x y

Le implementazioni dell'interfaccia vengono ereditate, pertanto eventuali classi derivate non necessitano di reimplementarle.

Chiamata di metodi di interfaccia

I metodi di interfaccia possono essere chiamati solo tramite l'interfaccia, non tramite qualsiasi oggetto del tipo che implementa l'interfaccia. Potrebbe pertanto essere necessario eseguire l'upcast al tipo di interfaccia utilizzando l'operatore :> o l'operatore upcast per chiamare questi metodi.

Per chiamare il metodo di interfaccia quando si dispone di un oggetto di tipo SomeClass, è necessario eseguire l'upcast dell'oggetto al tipo di interfaccia, come illustrato nel codice seguente.

let x1 = new SomeClass1(1, 2.0)
(x1 :> IPrintable).Print()

Un'alternativa consiste nel dichiarare un metodo nell'oggetto che consente di eseguire l'upcast e di chiamare il metodo di interfaccia, come nell'esempio seguente.

type SomeClass2(x: int, y: float) =
   member this.Print() = (this :> IPrintable).Print()
   interface IPrintable with
      member this.Print() = printfn "%d %f" x y

let x2 = new SomeClass2(1, 2.0)
x2.Print()

Implementazione di interfacce tramite espressioni dell'oggetto

Le espressioni dell'oggetto consentono di implementare velocemente un'interfaccia. Sono utili quando non è necessario creare un tipo denominato e si desidera soltanto un oggetto che supporti i metodi di interfaccia, senza metodi aggiuntivi. Un'espressione dell'oggetto è illustrata nel codice seguente.

let makePrintable(x: int, y: float) =
    { new IPrintable with
              member this.Print() = printfn "%d %f" x y }
let x3 = makePrintable(1, 2.0) 
x3.Print()

Ereditarietà di interfaccia

Le interfacce possono ereditare da una o più interfacce di base.

type Interface1 =
    abstract member Method1 : int -> int

type Interface2 =
    abstract member Method2 : int -> int

type Interface3 =
    inherit Interface1
    inherit Interface2
    abstract member Method3 : int -> int

type MyClass() =
    interface Interface3 with
        member this.Method1(n) = 2 * n
        member this.Method2(n) = n + 100
        member this.Method3(n) = n / 10

Vedere anche

Riferimenti

Espressioni di oggetto (F#)

Classi (F#)

Altre risorse

Riferimenti per il linguaggio F#

Cronologia delle modifiche

Data

Cronologia

Motivo

Sostituire con la data della modifica.

Sono state aggiunte informazioni sull'ereditarietà dell'istanza.

Miglioramento delle informazioni.