protocolについて整理する



##はじめに
MVPを勉強する上で、protocolを使うため整理しておこうと思います。


##protocolとは？
swiftにおいて、ポロパティやメソッドを定義することができ
クラスや構造体に準拠されることを前提で使われる物。

```
protocol HogeProtocol {
    var hoge: String { get }
    func doHoge()
}
//このように定義
```

##使用方法
クラスや構造体などに準拠されて使用します。

```
class Hoge: HogeProtocol {
    // 実装しなければエラーが発生する
    // var hoge: String = ""

    func doHoge() {
        print("doHoge")
    }
}
```
そして、最大の特徴はprotocolで定義したものは必ず実装しなければエラーになるということです。

##複数準拠が可能

クラスの場合、複数の継承はエラーが発生しますが
protocolでは複数準拠が可能です。

```
protocol FugaProtocol {
    var fuga: String { get }
    func doFuga()
}

protocol HogeProtocol {
    var hoge: String { get }
    func doHoge()
}

class HogeFuga: HogeProtocol, FugaProtocol {
    var hoge: String = ""
    var fuga: String = ""

    func doHoge() {
        print("doHoge")
    }

    func doFuga() {
        print("doFuga")
    }
}
```

##protocolのメリット
使い方は分かったけど、実際どういう時に使うの？
とい疑問が。
protocolを使わない場合と使った場合の２パターンを見ていきます。

###①protocolを使わない場合

まず大元の人間クラスを作ります。

```
class Human {
    var attackPower: Int?
    var defencePower: Int?

    func　attack() {
        guard let　attackPower =attackPower else { return }
        print("攻撃力は\(String(describing:attackPower))です")
    }

    func　defence() {
        guard let　defencePower =defencePower else { return }
        print("防御力は\(String(describing: swimmingSpeed))です")
    }
}
```

次は戦士クラスを作ってHumanクラスを継承します。

```
class Senshi:Human {
    override init() {
        super.init()
       attackPower = 36
       defencePower = 15
    }
}
```

次は魔法使いクラスを作りたいと思います。

魔法を使うのでmagicPowerメソッドを追加したいので
大元のHumanクラスに追加しないといけません。

```
class Human {
    var attackPower: Int?
    var defencePower: Int?
    var magicPower：Int？

    func　attack() {
        guard let　attackPower =attackPower else { return }
        print("攻撃力は\(String(describing:attackPower))です")
    }

    func　defence() {
        guard let　defencePower =defencePower else { return }
        print("防御力は\(String(describing: swimmingSpeed))です")
    }

func　magic() {
        guard let　magicPower =magicPowerelse { return }
        print("魔法力は\(String(describing:magicPower))です")
    }
}
```
さきほどの戦士クラスのほかに魔法使いクラスを用意します。

```
class Senshi:Human {
    override init() {
        super.init()
       attackPower = 36
       defencePower = 15
    }
}

class Mahoutukai:Human {
    override init() {
        super.init()
       magicPower = 30
       defencePower = 7
    }
}
```
これで出力できそうですが、
１つ問題が。

本来呼び出してはいけないメソッドを呼び出すことができてしまいます。

```
let Senshi = senshi()
let Mahoutukai = mahoutukai()

senshi.magic()
//出力なし


ｍahoutukai.attack()
//出力なし

```

###②protocolを使用する場合

```

protocol AttackProtocol {
    var attackPower: Int { get set }
    func attack()
}
// 同じ処理の部分はextentionでデフォルト実装していく
extension AttackProtocol {
    func attack() {
        print("攻撃力は\(String(describing:attackPower))です")
    }
}

protocol DefenceProtocol {
    var defencePower: Int { get set }
    func　defence()
}

extension　DefenceProtocol {
    func　defence() {
        print("防御力は\(String(describing:defencePower))です")
    }
}

protocol MagicProtocol {
    var　ｍagicPower: Int { get set }
    func magic()
}

extension MagicProtocol {
    func magic() {
        print("魔法力は\(String(describing:ｍagicPower))です")
    }
}

```

そしてクラスたちに準拠していきます。

```
class Senshi:Human, AttackProtocol,DefenceProtocol{
       attackPower:Int = 36
       defencePower:Int = 15
}

class Mahoutukai:Human,MagicProtocol,DefenceProtocol {
       magicPower:Int = 30
       defencePower:Int = 7
}


let Senshi = senshi()
let Mahoutukai = mahoutukai()

senshi.attack()
//攻撃力は36です

senshi.magic()
//エラー

ｍahoutukai.attack()
//エラー

```

protocolに定義されていないものはエラーになるのでわかりやすいです。

このように部分的に処理を共通化させる事によって
必要な処理のみを実装できて可読性が向上しますね。


##終わりに
「Appleはプロトコル指向言語が欲しかったのでSwiftを作った」
とも言われてるみたいです。

Swiftを触っていく上では超重要な部分だと思うので、プロトコルの理解をさらに深めていきたいと思います。