Arabirimler (F #)

Arabirimler , diğer sınıfların uygulayan ilgili üye kümelerini belirler.

Syntax

// Interface declaration:
[ attributes ]
type [accessibility-modifier] 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.member1argument-list = method-body1
    member self-identifier.member2argument-list = method-body2

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

Açıklamalar

Arabirim bildirimleri, hiçbir üye uygulanmamalıdır hariç sınıf bildirimlerine benzer. Bunun yerine, tüm Üyeler anahtar sözcüğüyle gösterildiği gibi soyuttur abstract . Soyut yöntemler için bir yöntem gövdesi sağlamazsanız. F # bir arabirim üzerinde varsayılan yöntem uygulaması tanımlanamaz, ancak C# tarafından tanımlanan varsayılan uygulamalarla uyumludur. Anahtar sözcüğünü kullanan varsayılan uygulamalar default yalnızca arabirim olmayan bir taban sınıftan devralınırken desteklenir.

Arabirimler için varsayılan erişilebilirlik public .

İsteğe bağlı olarak, her yöntem parametresine normal F # söz dizimini kullanarak bir ad verebilirsiniz:

type ISprintable =
    abstract member Print : format:string -> unit

Yukarıdaki ISprintable örnekte, Print yönteminin adında tek bir parametresi vardır string format .

Arabirim uygulamak için iki yol vardır: nesne ifadelerini kullanarak ve sınıf türlerini kullanarak. Her iki durumda da, sınıf türü veya nesne ifadesi, arabirimin soyut yöntemleri için yöntem gövdeleri sağlar. Uygulamalar, arabirimini uygulayan her türe özeldir. Bu nedenle, farklı türlerde arabirim yöntemleri birbirinden farklı olabilir.

interface end Basit sözdizimi kullandığınızda, tanımın başlangıcını ve bitişini işaretleyen anahtar sözcükler ve, isteğe bağlıdır. Bu anahtar sözcükleri kullanmıyorsanız, derleyici, kullandığınız yapıları çözümleyerek türün bir sınıf mı yoksa bir arabirim mi olduğunu çıkarmayın. Bir üye tanımlayabilir veya diğer sınıf sözdizimini kullanırsanız, tür bir sınıf olarak yorumlanır.

.NET kodlama stili, tüm arabirimlerin sermaye olarak başlamadır I .

Birden çok parametreyi iki şekilde belirtebilirsiniz: F # stili ve. NET stili. Her ikisi de .NET tüketicileriyle aynı şekilde derlenir, ancak f # stili f # çağıranlarını F # stili parametre uygulaması ve ile kullanmak için zorlayacaktır. NET stili, F # çağıranlarını tupled bağımsız değişken uygulaması kullanacak şekilde zorlayacaktır.

type INumericFSharp =
    abstract Add: x: int -> y: int -> int

type INumericDotNet =
    abstract Add: x: int * y: int -> int

Sınıf türlerini kullanarak arabirimleri uygulama

interfaceAşağıdaki kodda gösterildiği gibi anahtar sözcüğünü, arabirimin adını ve anahtar sözcüğünü kullanarak bir sınıf türünde bir veya daha fazla arabirim uygulayabilirsiniz with .

type IPrintable =
   abstract member Print : unit -> unit

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

Arabirim uygulamaları devralınır, bu nedenle türetilen sınıfların bunları yeniden uygulaması gerekmez.

Arabirim yöntemlerini çağırma

Arabirim yöntemleri, arabirimi uygulayan türdeki herhangi bir nesne yerine yalnızca arabirim üzerinden çağrılabilir. Bu nedenle, :> upcast Bu yöntemleri çağırmak için işlecini veya işlecini kullanarak arabirim türüne yukarı atama yapmanız gerekebilir.

Türünde bir nesneniz olduğunda arabirim yöntemini çağırmak için SomeClass , aşağıdaki kodda gösterildiği gibi, nesneyi arabirim türüne yukarı atamalısınız.

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

Alternatif olarak, aşağıdaki örnekte olduğu gibi, ve arabirim yöntemini çağıran nesne üzerinde bir yöntemi bildirmenin bir alternatifi.

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()

Nesne Ifadeleri kullanarak arabirimleri uygulama

Nesne ifadeleri, arabirim uygulamak için kısa bir yol sağlar. Adlandırılmış bir tür oluşturmanız gerekmeden ve yalnızca arabirim yöntemlerini destekleyen bir nesne istediğinizde, ek yöntemler olmadan bu yöntemler faydalıdır. Bir nesne ifadesi aşağıdaki kodda gösterilmiştir.

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()

Arabirim devralma

Arabirimler, bir veya daha fazla taban arabiriminden devralınabilir.

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

Varsayılan uygulamalarla arabirimleri uygulama

C#, varsayılan uygulamalarla arabirim tanımlamayı destekler, örneğin:

using System;

namespace CSharp
{
    public interface MyDim
    {
        public int Z => 0;
    }
}

Bunlar F # ' dan doğrudan tüketilebilir:

open CSharp

// You can implement the interface via a class
type MyType() =
    member _.M() = ()

    interface MyDim

let md = MyType() :> MyDim
printfn $"DIM from C#: %d{md.Z}"

// You can also implement it via an object expression
let md' = { new MyDim }
printfn $"DIM from C# but via Object Expression: %d{md'.Z}"

overrideHerhangi bir sanal üyeyi geçersiz kılmak gibi, ile varsayılan bir uygulamayı geçersiz kılabilirsiniz.

Varsayılan bir uygulamasına sahip olmayan bir arabirimdeki tüm üyelerin açıkça uygulanması gerekir.

Farklı genel örneklerde aynı arabirimi uygulama

F #, farklı genel örneklerde aynı arabirimi aynı şekilde uygulamayı destekler:

type IA<'T> =
    abstract member Get : unit -> 'T

type MyClass() =
    interface IA<int> with
        member x.Get() = 1
    interface IA<string> with
        member x.Get() = "hello"

let mc = MyClass()
let iaInt = mc :> IA<int>
let iaString = mc :> IA<string>

iaInt.Get() // 1
iaString.Get() // "hello"

Ayrıca bkz.