LoginSignup
2
1

More than 3 years have passed since last update.

プロトコルを定義する

Posted at

この投稿は何?

過去の投稿で、Swift標準ライブラリにある基本的なプロトコルをいくつか扱いました。
今回は、独自のプロトコルを定義して、準拠するまでを実践したいと思います。

実行環境

Xcode10.2.1
Swift5.x

ハンズオン

「フルーツを商品として扱う」みたいなケースを想定しています。

こんな型があったとして...

Fruit 型は果物を表現しています。
リンゴとオレンジをインスタンス生成しました。

フルーツ型
struct Fruit {
    var name:  String
    var emoji: String
    var sugarContent: Int
}

// インスタンスを生成
let apple  = Fruit(name: "Apple",  emoji: "🍎", sugarContent: 8)
let orange = Fruit(name: "Orange", emoji: "🍊", sugarContent: 11)

商品として販売するには

この Fruit 型を商品として扱うには欠けている情報があります。
例えば、価格とかですね。
単純にメンバープロパティとして、price を定義しても良さそうです。
ただ、商品として扱うのは Fruit 型オブジェクトだけとは限りません。
もしかしたら、ジュースとして Drink 型みたいなオブジェクトがあるかもしれません。
商品プロトコルを定義することにします。
そうすれば、商品として扱うなら価格が決まっていることが保証されますし、 price プロパティの実装を忘れることはありません。
ついでに、宣伝メッセージを出力してくれるメソッドもあるといいですね。

商品プロトコル
protocol Salable {
    var  price: Int { get set }
    func advertise()
}

プロトコルの定義では、具体的な値や実装はありません。
この時点で、金額が決まっていたり、宣伝文句を固定するのはおかしなハナシです。
また、プロパティは読み取り専用・読み書き可を明示する必要があります。

プロトコルに準拠する

Salable プロトコルを採用すると、エラーメッセージが表示されます。
Type 'Fruit' does not conform to protocol 'Salable'
Fixボタンを押すと、準拠に必要なプロパティおよびメソッドが自動的に記述されます。

販売可能なフルーツ
struct Fruit: Salable {
    var name:  String
    var emoji: String
    var sugarContent: Int
    var price: Int

    func advertise() {
        print("This \(name) is ¥\(price)")
    }
}

advertise メソッドは、この時点で具体的な実装を記述します。
プロトコルを採用した型次第で、実装をアレンジできます。

インスタンスを生成する

すでに生成したインスタンスはプロパティに初期値がないから、エラーになります。
初期化コードを修正します。

初期化コードを修正
let apple  = Fruit(name: "Apple",  emoji: "🍎", sugarContent: 8, price: 100)
let orange = Fruit(name: "Orange", emoji: "🍊", sugarContent: 11, price: 120)

プロトコルに準拠して、販売可能になったことを確認しましょう。

apple.advertise()    // This Apple is ¥100
orange.advertise()   // This Orange is ¥120

メッセージが出力されました。

Protocol-Oriented Programming

クラスには継承という概念がありますが、構造体に継承はありません。
一方で、Swiftプログラミングではクラスより構造体を使うことが推奨されているようです。
プロパティやメソッドの共用をプロトコルで設計することが POP の基本と感じました。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1