Arabirimler (F#)

Arabirimler , diğer sınıfların uyguladığı ilgili üye kümelerini belirtir.

Sözdizimi

// 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 uygulanmamış olması dışında sınıf bildirimlerine benzer. Bunun yerine, anahtar sözcüğüyle abstractgösterildiği gibi tüm üyeler soyut olur. Soyut yöntemler için bir yöntem gövdesi sağlamazsınız. F# bir arabirimde varsayılan yöntem uygulamasını tanımlayamaz, ancak C# tarafından tanımlanan varsayılan uygulamalarla uyumludur. anahtar sözcüğünü default kullanan varsayılan uygulamalar yalnızca arabirim olmayan bir temel sınıftan devralma sırasında desteklenir.

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

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

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

Yukarıdaki ISprintable örnekte yöntemi, Print adlı formattüründe string tek bir parametreye sahiptir.

Arabirimleri uygulamanın iki yolu vardır: nesne ifadelerini kullanarak ve türleri kullanarak. Her iki durumda da tür veya nesne ifadesi, arabirimin soyut yöntemleri için yöntem gövdeleri sağlar. Uygulamalar, arabirimi uygulayan her türe özeldir. Bu nedenle, farklı türlerdeki arabirim yöntemleri birbirinden farklı olabilir.

Basit söz dizimi kullandığınızda, tanımın başlangıcını ve sonunu işaretleyen ve endanahtar sözcükleri interface isteğe bağlıdır. Bu anahtar sözcükleri kullanmazsanız, derleyici kullandığınız yapıları analiz ederek türün bir sınıf mı yoksa arabirim mi olduğunu çıkarsamaya çalışır. Bir üye tanımlarsanız veya başka bir sınıf söz dizimi kullanırsanız, tür sınıf olarak yorumlanır.

.NET kodlama stili, tüm arabirimleri büyük Iharfle başlatmaktır.

Birden çok parametreyi iki şekilde belirtebilirsiniz: F#style ve . NET stili. Her ikisi de .NET tüketicileri için aynı şekilde derlenir, ancak F#style F# çağıranları F#style parametre uygulamasını ve kullanmaya zorlar. NET stili, F# çağıranlarını yinelenen bağımsız değişken uygulamasını kullanmaya zorlar.

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

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

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üretilmiş sınıfların bunları yeniden ataması gerekmez.

Arabirim Yöntemlerini Çağırma

Arabirim yöntemleri, arabirimi uygulayan türün herhangi bir nesnesi aracılığıyla değil, yalnızca arabirim aracılığıyla çağrılabilir. Bu nedenle, bu yöntemleri çağırmak için işlecini :> veya upcast işlecini kullanarak arabirim türüne yükseltmeniz gerekebilir.

türünde SomeClassbir nesneniz olduğunda arabirim yöntemini çağırmak için, aşağıdaki kodda gösterildiği gibi nesnesini arabirim türüne yukarı yayınlamalısınız.

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

Alternatif olarak, aşağıdaki örnekte olduğu gibi yukarı yayınlayan ve arabirim yöntemini çağıran nesnede bir yöntem bildirilir.

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 İfadelerini Kullanarak Arabirimleri Uygulama

Nesne ifadeleri bir arabirim uygulamak için kısa bir yol sağlar. Adlandırılmış bir tür oluşturmanız gerekmediğinde ve herhangi bir ek yöntem olmadan yalnızca arabirim yöntemlerini destekleyen bir nesne istediğinizde kullanışlıdır. 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 temel arabirimden devralabilir.

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# aşağıdaki gibi varsayılan uygulamalarla arabirim tanımlamayı destekler:

using System;

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

Bunlar doğrudan F# ile kullanılabilir:

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}"

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

Varsayılan uygulaması olmayan bir arabirimdeki tüm üyeler yine de açıkça uygulanmalıdır.

Farklı genel örneklemelerde aynı arabirimi uygulama

F# aşağıdaki gibi farklı genel örneklemelerde aynı arabirimin uygulanmasını 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.