> For the complete documentation index, see [llms.txt](https://kurohasu.gitbook.io/fsharpabout/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kurohasu.gitbook.io/fsharpabout/objects/abstract-interface.md).

# 抽象クラスとインターフェース

### メソッドの再定義

F#では\
①引数の型と戻り値の型のみを定義した「抽象クラス」\
②受け渡しを行う「インターフェース」\
がサポートされています。これらを用いることで

### 抽象クラス

抽象クラスは記述の通り、引数と戻り値の型のみが記述されているクラスで継承先にて内部のプログラムを実装します。クラスの派生をするときに共通のものを返してほしい時に便利です。\
またdefaultを用いて継承先で実装が無い場合の処理の記述も行えます

```
構文:
    ①デフォルト処理が無い場合
    abstract member 抽象クラス名:<引数の型> -> <戻り値の型>

    ②デフォルト処理がある場合
    abstract member 抽象クラス名:<引数の型> -> <戻り値の型>
    default 自己識別子.抽象クラス名(<引数>)=処理...

実装:
    override 自己識別子.抽象クラス名(<引数>)=処理...
```

### インターフェース

クラスの仕様としての型を定義するもので簡単に言うと「外部からどう見えるか」を重視しています。\
継承先でインターフェースの実装を行い、アップキャストして呼び出す必要があります。

```
構文:
    type インターフェース名=
        abstract member 処理名:<引数の型> -> <戻り値の型>
        ...

実装:
    interface インターフェース名　with
        member 自己識別子.処理名(<引数>)=処理...
    ...

呼び出し:
    ①クラス内で実装＆呼び出せるようにする(こっちがおすすめ)
    member this.処理名=(this:>インターフェース名).処理名(<引数>)
    

    ②インスタンスにアップキャスト
    (インスタンス:>インターフェース名).処理名(引数)
```

### 実装例

<pre class="language-fsharp"><code class="lang-fsharp"><strong>//①抽象クラス
</strong>
type absclasses()=    //抽象クラス「absclasses」
    
    abstract member msglength:string->int
    default _.msglength(txt)=String.length(txt)    //文字列の長さを返す

    
type absimp()=
    inherit absclasses()
    override _.msglength(txt)=String.length(txt)*2    //文字列の長さ*2を返す


//呼び出し
absimp().msglength("あいうえお")


//出力:10
</code></pre>

```fsharp
//②インターフェース

type Icall=    //インターフェース「Icall」
    abstract member Call:unit->unit    //unitを受け取りunitを返す

//実装
type jissou2()=
    member this.Call()=(this :> Icall).Call()    //メンバーにアップキャスト

    interface Icall with    //インターフェースの利用を宣言
        member _.Call()=printfn "interface used"


//呼び出し
jissou2().Call()


//出力:interface used
```
