インタフェース
インタフェースを使うことで
「このメソッドは必ず実装するように」というような
制約をクラスに持たせることが出来ます。
インタフェースは、抽象メソッドとプロパティのみを持つことができ、
デフォルトの実装は提供しません。
また直接インスタンス化することも出来ません。
クラスに実装するか、
後述するObject Expressionを通して利用していくことになります。
インタフェースの構文は次の通りです
- インタフェース
-
type インタフェース名 = interface
継承宣言
メンバ定義
end
interfaceとendは軽量構文時は省略出来ます。
抽象メソッドの回の説明で作成した抽象メソッドを
インタフェースにしたのが次です。
インタフェースの例
type IAnimal = interface
abstract member Bark : unit -> unit
end;;
インタフェースの例(軽量構文)
type IAnimal =
abstract member Bark : unit -> unit
これを用いて前回のプログラムを書き直すと
次のようになります。
インタフェースの利用例
type IAnimal = interface
abstract member Bark : unit -> unit
end;;
type Dog() = class
interface IAnimal with
member this.Bark () = printfn "わんわん"
end
end;;
type Cat() = class
interface IAnimal with
member this.Bark () = printfn "ニャー"
end
end;;
let d = new Dog();;
// d.Bark();; //これはエラー
(d :> IAnimal).Bark();;
let c = new Cat();;
(c :> IAnimal).Bark();;
インタフェースの利用例
type IAnimal =
abstract member Bark : unit -> unit
type Dog() =
interface IAnimal with
member this.Bark () = printfn "わんわん"
type Cat() =
interface IAnimal with
member this.Bark () = printfn "ニャー"
let d = new Dog()
// d.Bark() //これはエラー
(d :> IAnimal).Bark()
let c = new Cat()
(c :> IAnimal).Bark()
インタフェースの実装の構文は次の通りです。
- インタフェースの実装
-
interface インタフェース名 with
値またはメンバの定義
end
ちょっとイケてないと思うのは
コメントアウトしている箇所のように記述できない点です。
これをキャストなしで済ますには、
次のようにする必要があります。
インタフェースの利用例2
type IAnimal = interface
abstract member Bark : unit -> unit
end;;
type Dog() = class
interface IAnimal with
member this.Bark () = printfn "わんわん"
end
member this.Bark () = (this :> IAnimal).Bark()
end;;
type Cat() = class
interface IAnimal with
member this.Bark () = printfn "ニャー"
end
member this.Bark () = (this :> IAnimal).Bark()
end;;
let d = new Dog();;
d.Bark();;
let c = new Cat();;
c.Bark();;
インタフェースの利用例2(軽量構文)
type IAnimal =
abstract member Bark : unit -> unit
type Dog() =
interface IAnimal with
member this.Bark () = printfn "わんわん"
member this.Bark () = (this :> IAnimal).Bark()
type Cat() =
interface IAnimal with
member this.Bark () = printfn "ニャー"
member this.Bark () = (this :> IAnimal).Bark()
let d = new Dog()
d.Bark()
let c = new Cat()
c.Bark()
二度手間になってしまいますがクラスのBarkの実装を
インターフェースの実装に委譲しています。
インタフェースの継承
インタフェースはインタフェースを継承することも出来ます。
継承にはinheritキーワードを用います。
インタフェースの継承
type IA = interface abstract One : int -> int end;;
type IB = interface abstract Two : int -> int end;;
type IC = interface
inherit IA
inherit IB
abstract Three : int -> int
end;;
インタフェースの継承(軽量構文)
type IA = abstract One : int -> int
type IB = abstract Two : int -> int
type IC =
inherit IA
inherit IB
abstract Three : int -> int
インタフェースは複数継承することができます。
ICはIAとIBを継承しているため
One,Two,Three3つの抽象メソッドを持ちます。
そして、これを定数関数として実装したのが次の例です。
継承したインタフェースの利用
type ClassWithIC() = class
interface IC with
member x.One _ = 1
member x.Two _ = 2
member x.Three _ = 3
end
end;;
継承したインタフェースの利用(軽量構文)
type ClassWithIC() =
interface IC with
member x.One _ = 1
member x.Two _ = 2
member x.Three _ = 3
このように、継承して作成したインタフェースも
通常のインタフェースと同様に利用することができます。