【java】基本構文（インターフェース・抽象クラス編）

# はじめに
Java一年未満の方へ研修用
インターフェース・抽象クラスに関して少し掘り下げて紹介

# 対象
・Java一年未満

# はじめに
・似たような機能である「継承」については混乱するので一旦忘れましょう。

# インターフェースとは
・クラスに含まれるメソッドの具体的な処理内容を記述せず、変数とメソッドの型のみを定義したもの
・インターフェイスと実装クラスの「実装」の関係はCAN DOの関係と言われています。
　(レジ CAN bill クレジットカード＝レジはクレジットカード会計が出来る。のような関係)

# 具体的に言うと
コンセントで表現するとわかりやすいです。

１．コンセントの規格が決まり、電化製品は基本的にはその規格に沿ったコンセントを作る必要があることになった（インターフェース）
２．冷蔵庫を作った
３．テレビを作った
４．炊飯器作った

家電のコンセントの形が全て統一されていれば、全て同じ電源タップが使える。
家電ごとに変換機を買ってきたり、工事をしてコンセントの形を変えたりなどということは不要になる。
家電の開発者は「コンセントの形を統一するというルール」の元、開発しており、それがインターフェースの本質。

★以下の図のコンセントの部分が「インターフェース」です。
![スクリーンショット 2023-01-15 12.14.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2956190/e2ca4959-9da7-d344-8d94-6df2ed465632.png)

# インターフェースを使うメリット
・規格を揃えることで今後の開発をスムーズにすることができる
・「未来に作られるプログラムたち」の為のルールであり、今は無い機能を追加する際に、このインターフェースにより、「ルール」が決まっている場合、既存の機能を修正することなく、実装できたりする。

# javaでのインターフェースの使い方
以下のように定義します。
```
//インターフェースの宣言
interface インターフェース名{}

//インターフェースの実装
class クラス名 implements インターフェース名{}
```

# 具体的な実装例
レジとそれを使う店員を例に実装してみる

レジインターフェースに会計メソッドを定義します。
```
public interface Cashier {
    public void bill();
}
```
次にインターフェースを実装し、クレジットカードでの会計を実装します。
```
public class CreditCard implements Cashier{
    @Override
    public void bill() {
        System.out.println("クレジットカードで会計する。");
    }
}
```
次にインターフェースを実装し、現金での会計を実装します。
```
public class Cash implements Cashier{
    @Override
    public void bill() {
        System.out.println("現金で会計する。"); 
    }
}
```
店員はレジの会計を実施します。
この時Cashier#billを呼び出しているので、これが現金会計なのかクレジット会計なのかは
意識せずに使う事ができます。
```
public class Staff {
    public static void main(String[] arg) {
        Cashier cash = new Cash();
        Cashier credit = new CreditCard();

        System.out.println("現金");
        cash.bill();

        System.out.println("クレジット");
        credit.bill();
    }
}
```

# その他
・インターフェースは多重継承が可能です。
　※クラスは多重継承できない、インターフェースは多重継承できるだけ覚えておきましょう。

# 抽象クラスとは
・abstract（抽象）とも呼ばれ、抽象メソッドを1つ以上持つクラスを指します。
　抽象メソッドは具体的な処理内容を記述せず、メソッド名や引数などの定義だけを宣言するメソッド。
・抽象クラスを継承したサブクラス（子クラス）で抽象メソッドをオーバーライドし処理を記述する。

※抽象メソッドとは実装を持たない、シグネチャ(メソッド名、引数の型、引数の数)と戻り値の型のみを定義するメソッド

# 具体的に言うと
抽象クラスと具象クラス(処理の中身があるクラス)の「継承」関係はIS Aの関係と言われています。
犬 IS A 動物＝犬は動物だ　のような親子関係です。

動物クラス（抽象クラス）に犬や人間が持っている共通動作（処理）を書きましょう。と言われている。
(子供のみんなが出来ることを抽象的に抽象クラスに書いて、その子にしか出来ない具体的なことは具象クラスに書くみたいな感覚)

# 抽象クラスを使うメリット
・メソッドのオーバーライドを強制できる

# javaでの抽象クラスの使い方
```
public abstract class AbstractClass {
    public abstract void abstractMethod(int num, String str);★抽象メソッド
}
```
```
★抽象クラスを継承したクラス
public class Main extends AbstractClass {

    public void abstractMethod(int num, String str) {
        System.out.println("引数int num = " + num + " / 引数String str = "+ str);
    } 
}
```

# 具体的な実装例
動物を例に実装例を記載してみる

抽象的に抽象クラスを考えると、動物は名前持っている。
そして夜は寝るし、ご飯を食べて、話すことが出来る。

寝る行動はどの動物も同じなので共通した抽象クラスで実装。
ご飯を食べるのも話すのも出来るが、具体的なことは動物によって異なるので、抽象メソッドとして定義。

```
public abstract class Animal {
    String name;

    public Animal(String name){
        this.name = name;
    }

    public void sleep(){
        System.out.println("寝る");
    }
    public abstract void speak();

    public abstract void eat();
}
```
次に犬の話し方と食べ方は違うので具象クラスで具体的に実装。
```
public class Dog extends Animal{

    public Dog(String name){
        super(name);
    }

    @Override
    public void speak() {
        System.out.println("私の名前は"+name+"だワン！！");
    }

    @Override
    public void eat() {
        System.out.println("ガブガブガブ");
    }
}
```
次に人間で具体的に実装。
```
public class Human extends Animal{

    public Human(String name) {
        super(name);
    }

    @Override
    public void speak() {
        System.out.println("初めまして、私の名前は"+name+"です。");       
    }

    @Override
    public void eat() {
        System.out.println("もぐもぐ");     
    }
}
```

# まとめ
・抽象クラスと具象クラスの「継承」関係はIS Aの関係であり、親クラスには抽象的に子供達が出来ることをまとめる。
・インターフェイスと実装クラスの「実装」の関係はCAN DOの関係であり、インタフェースには出来る事のみを定義し、具体的なことは実装クラスにお任せします。使う側は中で実装された詳細は気にする必要が無くなる。

・抽象クラスは、共通の処理をまとめたりする中で使う人のためにある
・インタフェースは、詳細は見せず出来ることを定義し、外から使う人のためにある