インターフェイス
F#でも、C#同様、クラスは複数のインターフェイスを実装できます。
インターフェイスはクラスと似ていますが、メンバーはすべて抽象メンバーとなります。defaultキーワードを使用してメソッドのデフォルトの実装を定義することは可能です。
[ 属性 ] typeインターフェイス名 = [ interface ] abstract メンバー名1 : [ パラメータの型1 -> ] 戻り値の型1 abstract メンバー名2 : [ パラメータの型2 -> ] 戻り値の型2 ... [ end ] //クラス内での実装 interfaceインターフェイス名 with memberセルフ識別子.メンバー名1パラメータ = メソッド本体1 member セルフ識別子.メンバー名2パラメータ = メソッド本体2
インターフェイスの宣言と実装
実装はクラス型もしくは、オブジェクト式の2通りありますが、今回はクラス型の実装方法のみ紹介します。オブジェクト式での実装は、次回以降の連載で予定しているオブジェクト式の解説の際に紹介します。.NETのコーディングスタイルどおり、インターフェイス名の頭文字は”I”になります。
以下はインターフェイスの宣言と実装の例です。
//インターフェイス宣言 type ITestInterface = abstract member testMethod : unit -> unit //インターフェイス実装 type testClass(a : int, b : int) = interface ITestInterface with member this.testMethod() = printfn "%d %d" a b //メソッド呼び出し let x1 = new testClass(3, 4) //インターフェイス型へインスタンスをアップキャストする (x1 :> ITestInterface).testMethod();;
▼
3 4
インターフェイスのメソッドはインターフェイス経由でのみ呼び出すことが可能です。そのため、オブジェクトを”:>”演算子や、”upcast”演算子を用いてインターフェイスの型へアップキャストする必要があります。アップキャスト(または、アップキャスティング)とは、派生(子)オブジェクトからベースオブジェクト(親)へ型変換することです。
オブジェクト名 :> ベース(親)オブジェクト型名
上記リスト9の例ですが、もう1つ別の方法として、クラス内でアップキャストしてメソッドを宣言する方法があります。
//インターフェイス宣言 type ITestInterface = abstract member testMethod : unit -> unit //インターフェイス実装(アップキャストしてメソッドを宣言) type testClass2(a : int, b : int) = member this.testMethod() = (this :> ITestInterface).testMethod() interface ITestInterface with member this.testMethod() = printfn "%d %d" a b //メソッド呼び出し let testObj2 = new testClass2(10, 20) testObj2.testMethod();;
▼
10 20
上記のリスト10では、メソッド呼び出し時にインスタンスをアップキャストする代わりに、実装時にメソッド自体をアップキャストしています。
アップキャストの逆、ベースオブジェクトから派生オブジェクトへの変換をダウンキャスト(ダウンキャスティング)と言います。ダウンキャストに関しては、一般的な概念同様ですがF#でも、オブジェクトが直接派生してない型へのダウンキャストは、コンパイル時にエラーが返されます。