20分でわかる？ JavaのInterfaceの基本


# サンプルコード
本記事ではゲームプログラムっぽいサンプルコードとともに、Interfaceそのもの・呼ばれる側・呼ぶ側の解説をする。Interfaceって何？という方向けの記事です。
## Interfaceファイル
メソッド（ふるまい）の定義を記載したファイル。
クラスではない。
```ゲームプログラムっぽいもの①.java
/** プレイヤーがアクセス可能である。*/
public interface アクセス可能なもの{

    /** アクセスされたときのふるまい。*/
    public void アクセスする();
}
```
上記の通り、メソッドの中身も空っぽでよく、
メソッドの定義（平たく言うと、呼び出し方）さえ書かれていればOK、というのがInterface。

乱暴に言うと、中身空っぽの定義ファイルである。
## Interfaceとして呼び出される側（Interfaceの実装クラス）
Interfaceは他のクラスに実装（Implement）されることで、使えるようになる。
```ゲームプログラムっぽいもの②.java
public class 宝箱 implement アクセス可能なもの{

    public void アクセスする(){
        //中身を獲得する処理。
    }
}

public class 商人 implement アクセス可能なもの{

    public void アクセスする(){
        //取引画面を開く処理。
}
```
メソッドの名前や引数などはInterfaceに従う必要がある。
が、メソッドの中身の処理は実装クラス側が好きに決められる。
なので、処理は同じでも良いし、全く違っても良い。**自由。**

上記例の「商人」と「宝箱」というのは、客観的に見て、関連が薄い機能ではあるが、
「プレイヤーがアクセス可能」という1点だけに注目すると、共通であるともいえる。

乱暴な言い方にはなるが、
Interface記載のふるまいを実装しよう！と思ったクラスには、Interfaceは実装して**よい**。
（ここでは「プレイヤーがアクセス可能である」というのが「ふるまい」）

注意点だが、Interfaceを実装(Implements）する場合、Interfaceのメソッドは
漏れなく使えるようにしておかないといけない。
上記の例では「アクセスする」メソッドをクラスにて使える状態にしておく必要がある。
そうでないと、コンパイルエラーになってしまう。

## Interfaceを呼び出す側
呼び出す処理のほうも書いてみる。
以下を見るとわかるが、呼び出す側は、Interfaceと階層的に関係する必要はなく、Interface名と呼び出すメソッドを知っているだけで良い。

```ゲームプログラムっぽいもの③.java
    public void 〇ボタンを押す(){

    //近隣のアクセス可能な対象から最も近いものを取得する機能（詳細略）
    アクセス可能なもの accessable=getAccessable(); 

    //取得した対象にアクセスする。
    accessable.アクセスする();
    }
}
```
ここで注目してほしいのだが、
呼び出す側のコードには、「宝箱」「商人」といった要素が一切出てきていない。
「アクセス可能なもの」に対して「アクセスする」という抽象的な表現になっている。

抽象的に書ける、ということは、実は非常にありがたい。なぜなら、
・宝箱に対する呼び出しコード
・商人に対する呼び出しコード
をそれぞれに書く必要がないからである。

もっと言うと、「ちょっとレアな宝箱」だの「秘密のボタン」だの、
アクセス可能な対象を増やされても安心だといえる。

**＜＜以降、抽象的にあつかえるというのは原則良い、という立場で記載します＞＞**

# Interfaceの使われどころ
Interfaceが使われる場合、下記のうちの1つ、もしくは組み合わせが目的であることが多い。

## 自由な継承
クラスの継承元、すなわち「親」は1つのみ、というのがJavaの大原則、ルールである。
```BadExtends.java
public class Child extends Parent1,Parent2{
 //コンパイルエラーになる。
}
```
が、Interfaceはいくつでも実装元として使える。
```GoodImplements.java
public class Child Implements Interface1,Interface2{
 //問題なし。
}
```
抽象的なプログラミングを行う際、
Interface1という抽象名でも扱いたいが、Interface2という抽象名でも扱いたい・・・
というケースはよくある。
Interfaceは多重継承可能であるので特に気にせず、両方のInterfaceを実装できる。
## ソースに対するマーカー
Interfaceは中身が空っぽ、かつクラスにいくつも実装できる、という特徴は、
クラスに何かしらのマーキングをしたいというニーズにぴったりである。
この思想で使われているのがアノテーション（@xxx）という機能である。
アノテーションは、@InterfaceというInterfaceの一機能である。

## 自動生成の殻として
interfaceのメソッドは中身が空であり、
かつ、実装クラスが別で生成されるという特徴は、
自動生成ライブラリの思想とよく適合する。
（作りたい内容だけ定義し、中身はライブラリが自動生成したものを作成する）
domaやlombokなど。

# Interfaceでも中身を書きたいという場合
ガワもいいけど、やはり処理を共通化したい、というケースは往々にして発生する。
それに対するアンサーが、defaultメソッドと、（Interfaceの）staticメソッドである。
## defaultメソッド
defaultメソッドという仕組みがあり、中身の処理を記載できる。
```Example.java
/** プレイヤーがアクセス可能である。*/
public interface Example{

    /** 共通的な処理。*/
    public default void 共通的な処理(){
        //共通的な処理。
    }
}
```
## staticメソッド
こちらも同様に、中身の処理を記載できる。
```Example2.java
/** プレイヤーがアクセス可能である。*/
public interface Example2{

    /** 共通的な処理。*/
    public static void 共通的な処理(){
        //共通的な処理。
    }
}
```
defaultとの使い分けは、基本的には
staticというもののふるまい（インスタンス化されない、継承できない、など）に注意していただければよい。

# 余談
- Interfaceには、定数も定義できる。(public static finalな変数）
- Interfaceのクラス・メソッドは原則、publicであるとして扱われる。
- Java以外では、Interfaceという名前の機能はあまり見たことが無い。**抽象クラス**を使うことも多い気がする。動的型付け言語だと、**ダックタイピング**という思想が引き合いに出されることが多い。
- 後半ちょっと力尽きてます。
# 参考文献
徹底攻略 Java SE11 Silver問題集（インプレス）