共用方式為


介面 (F#)

「介面」(Interface) 可指定其他類別實作的相關成員集合。

// 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

備註

介面宣告類似類別宣告,不同的是未實作成員, 所有成員都是抽象,如同 abstract 關鍵字所表示。 您不必提供抽象方法的方法主體, 但是可以將做為方法的另一個成員定義與 default 關鍵字包含在一起,提供預設實作。 這樣做相當於以其他 .NET 語言建立基底類別的虛擬方法。 在實作介面的類別中可以覆寫這類虛擬方法。

使用物件運算式以及使用類別型別都可以實作介面。 無論哪種方式,類別型別或物件運算式都會提供介面之抽象方法的方法主體。 實作是每個實作介面之型別專屬的實作。 因此,不同型別的介面方法可能互異。

當您使用輕量型語法時,標示定義開頭和結尾的關鍵字 interface 和 end 是選擇性項目。 如果未使用這些關鍵字,編譯器會分析使用的建構,嘗試推斷型別是類別還是介面。 如果您定義成員或使用其他類別語法,型別就會解譯為類別。

.NET 程式碼撰寫風格是以大寫字 I 做為所有介面的開頭。

使用類別型別來實作介面

您可以使用 interface 關鍵字、介面名稱和 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

會繼承介面實作,因此任何衍生類別都不需要重新實作它們。

呼叫介面方法

介面方法只能透過介面來呼叫,不能透過實作介面之任何型別的物件來呼叫。 因此,您必須使用 :> 運算子或 upcast 運算子向上轉型為介面型別,才能呼叫這些方法。

當物件的型別為 SomeClass 時,若要呼叫介面方法,您必須將物件向上轉型為介面型別,如下列程式碼所示。

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

另一個方式是在向上轉型及呼叫介面方法的物件上宣告方法,如下列範例所示。

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

使用物件運算式來實作介面

物件運算式可提供實作介面的捷徑。 當您不必建立具名型別,只要支援介面方法但不包含其他方法的物件時,物件運算式會很有用。 在下列程式碼中,會示範物件運算式的用法。

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

介面繼承

介面可以繼承一個或多個基底介面。

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

請參閱

參考

物件運算式 (F#)

類別 (F#)

其他資源

F# 語言參考

變更記錄

日期

記錄

原因

以變更日期取代。

新增關於介面繼承的資訊。

資訊加強。