>100 Views
July 12, 15
スライド概要
#yidev 横浜 iPhone 開発者勉強会の第20回目で発表しようと思って用意した、クラス継承の特徴とプロトコル拡張の特徴の違いをざっくり比較してみたスライドです。スライドだけだと足りない部分もあるかと思いますけど、せっかくなので公開しておきます。
※ Docswell での公開に移行する直前の Slideshare での閲覧数は 20,507 でした。
正統派趣味人プログラマー。プログラミングとは幼馴染です。
Swift カジュアルプログラミング クラス継承とプロトコル拡張 2015.07.11 @ yidev 第20回勉強会 EZ-‐‑‒NET 熊⾕谷友宏 http://ez-‐‑‒net.jp/
熊谷友宏 EZ-NET http://ez-net.jp/ @es̲kumagai Xcode 5 徹底解説 MOSA IP Phone 音でダイヤル いつもの電卓 with 割勘ウォッチ 音で再配達ゴッド
WWDC2015 情報共有会で プロトコル拡張について発表してきました。 @yucovin @esum1527 @akio0911 http://connpass.com/event/16691/
発表後にツイッターを眺めていると 『プロトコル拡張って多重継承の一種?』
そこで
クラス継承とプロトコル拡張を ざっくり比較してみる
多重継承
クラス継承
クラス継承 機能を特化して積み上げる ⽣生きる機能を実装 消化器・循環器・呼吸器など ⾷食事を⾁肉に限定 必要な機能を実装 ⽣生物 動物 ⾁肉⾷食 猫 動く機能を実装 運動神経・関節など にゃーと鳴く、⽑毛繕いなど 猫らしい機能の実装 目的に特化 広くを想定
クラス継承 今までの資産を活かせる 機能を流流⽤用して 新しいものを⽣生成 ⽣生物 ⽝犬 動物 ⾁肉⾷食 猫 ⽝犬 ▶ 制作コストの削減 ▶ どちらも “動物” として 扱える
クラス継承 特徴を併せ持つとき 草⾷食機能を独⾃自実装? ⽝犬って雑⾷食 ⽣生物 ⽝犬 動物 ⾁肉⾷食 猫 ⽝犬 ▶ 犬で雑食性を追加?
クラス継承 特徴を併せ持つとき 草⾷食動物を作って継承? 草⾷食 雑⾷食性 ⽝犬 ⽣生物 動物 ⾁肉⾷食 純⾁肉⾷食 猫 ⽝犬 ▶ 肉食と草食を継承? 多重継承 (C++)
プロトコル拡張
プロトコル 特徴で対象を説明する ⾁肉⾷食型 鳴ける 猫 ⾛走れる 歩ける ▶ 対象は猫型 ▶ 特徴をプロトコルで表現
プロトコル拡張 特徴に機能を添える ⾁肉を⾷食べさせる ⾁肉⾷食型 鳴ける 猫 鳴かせる ⾛走れる 前に進ませる 歩ける 右を向かせる ▶ プロトコルに 機能を関連付ける
プロトコル指向 特徴を型で具現化する ⾁肉を⾷食べさせる ⾁肉⾷食型 鳴ける 猫 ⾛走れる 前に進ませる 歩ける 右を向かせる 鳴かせる 特徴の実現に必要な 猫固有の機能を実装 にゃーと鳴くのはここで実装 ▶ 必要最低限の機能を 型に実装する
プロトコル指向 対象ごとに特徴から組み立てる 鳴ける ⾁肉⾷食型 猫 ⾁肉⾷食型 ⾛走れる 草⾷食性 ⾛走れる 歩ける 歩ける ⽝犬 吠え れる
プロトコル指向 複数のプロトコル拡張を継承 鳴かせる 鳴ける ⾁肉⾷食型 ⾁肉を⾷食べさせる 猫 ⾁肉⾷食型 ⾛走れる 草⾷食性 前に進ませる 歩ける 右を向かせる 歩ける ⾛走れる 草を⾷食べさせる ⽝犬 吠え れる 吠えさせる
多重継承?
特徴を観察
クラス継承
クラス継承 紛れもない多重継承 草⾷食 ⽝犬 ⽣生物 動物 ⾁肉⾷食 猫 ⽝犬 ▶ 同じ機能があると複雑に ▶ どちらを使ったら良いか
クラス継承 紛れもない多重継承 草⾷食 ⽝犬 ⽣生物 動物 ⾁肉⾷食 猫 ⽝犬 ▶ 共通する親を持つ場合が さらに話を難しくする
プロトコル拡張
プロトコル拡張 特徴それぞれが機能を持つ ⾁肉を⾷食べさせる ⾁肉⾷食型 草を⾷食べさせる 草⾷食性 前に進ませる 右を向かせる 歩ける ⾛走れる ⽝犬 吠えさせる 吠え れる ▶ 複数の特徴を継承する ▶ 多重継承にも似ているが それぞれの階層は浅い
プロトコル拡張 継承に見えるところ ⾁肉を⾷食べさせる ⾁肉⾷食型 草を⾷食べさせる 草⾷食性 前に進ませる 右を向かせる 歩ける ⾛走れる ⽝犬 吠えさせる 吠え れる ▶ “歩ける” を継承して “走れる” を作っている?
プロトコル拡張 継承というより 上位 合わせてひとつ? 歩けて・走れる ⾛走れる 進ませる (⾛走り) 歩ける 進ませる (歩き) ⾛走れる 進ませる (⾛走り) 右を向かせる 歩ける 進ませる (歩き) 下位 右を向かせる ▶ 上位へ進化というより 特徴をあわせ持つ? ▶ 優位性は若干ある
守備範囲を観察
クラス継承
クラス継承 肉食動物の守備範囲 ⽣生物 動物 ⾁肉⾷食 猫 ⽝犬 ▶ 生物の起源までが範疇
プロトコル拡張 肉食動物の守備範囲 ⾁肉を⾷食べさせる 前に進ませる 右を向かせる 歩ける ⾁肉⾷食型 猫 ⾛走れる 鳴かせる 鳴ける ▶ 肉を食べれること、以上
影響範囲を観察
クラス継承 犬に雑食性をもたせたくなったら “なんでも⾷食べる” を再解禁 ⿅鹿鹿 ⽝犬 ! ! 草⾷食 ! ! 動物 ⾁肉⾷食 猫 ⽝犬 ? ⽣生物 “なんでも⾷食べる” を追加 ⾁肉⾷食に制限 ▶ 多重継承が無理なら 動物で受け入れる? ▶ 猫にも影響が及ぶかも
プロトコル指向 犬に雑食性をもたせたくなったら ⾁肉⾷食型 草⾷食性 ⾛走れる ⽝犬 ! 吠え れる ⾁肉⾷食型 ⾛走れる 猫 鳴ける ⾛走れる ⿅鹿鹿 ▶ 犬に草食性をプラス 草⾷食型 ▶ 他には影響しない
クラス継承 生物の常識を覆す新発見 !? ! ⿅鹿鹿 ! ! ⽝犬 ! 猫 ⽝犬 ! 草⾷食 ! ! 動物 ⾁肉⾷食 ⽣生物 新種 ♪ ▶ 生物界に激震
プロトコル指向 生物の常識を覆す新発見 !? ⾁肉⾷食型 草⾷食性 ⾛走れる ⽝犬 吠え れる ⾁肉⾷食型 ⾛走れる 猫 鳴ける ⾛走れる 新常識識 ⿅鹿鹿 ♪ ▶ 新しいプロトコルが 草⾷食型 生まれるかも
可読性を観察
クラス継承 犬って雑食? 草⾷食ではなさそう 草⾷食 ⽝犬 動物 ⾁肉⾷食 猫 ⽝犬 ⽣生物 とりあえず⾷食べれる でも⾁肉だけみたい ▶ 表面から分からない? ▶ 読み解く必要がある
プロトコル 犬って雑食。 ⾁肉⾷食型 草⾷食性 ⾛走れる 歩ける ⽝犬 吠え れる ▶ プロトコルで一目瞭然
実装を観察
クラス継承 汎用的な土台から積み上げる ⽝犬 猫 ⾁肉⾷食 ⾁肉⾷食 動物 動物 ⽣生物 ⽣生物 ▶ 土台の設計が重要 ▶ 汎用化が鍵?
プロトコル拡張 具体的な特徴で説明する ⾁肉⾷食型 草⾷食性 ⾛走れる ⽝犬 ⾁肉⾷食型 ⾛走れる 吠え れる 猫 鳴ける 動物 汎⽤用的すぎると 扱いにくそう ▶ 特徴の切り出しが重要 ⽣生物 ▶ 抽象化が鍵?
アクセス範囲を観察
クラス継承 継承先ほど狭める方向へ 親クラスをまるごと 秘密にはできない ⽣生物 親と同じか低い アクセス範囲が必要 動物 ⾁肉⾷食 ❌ Private ⭕ Public 猫 ⽝犬 Internal ▶ 親の公開範囲を 自分より狭くできない 親が internal なら子は internal 以下
プロトコル継承 継承先ほど狭める方向へ 元の想定範囲は 広げられない 元と同じか 狭いアクセス範囲で 歩ける ⾛走れる Internal ❌ Private ⭕ Public ▶ 元の公開範囲より 広いものは作れない 元が internal なら新しいものは internal 以下
型のプロトコル継承 アクセス範囲はそれぞれ次第 型より⼩小さい アクセス範囲も可能 ⭕ Private これが求める機能の範囲は このプロトコルの範囲以上で 集会 できる 歩ける ⾛走れる Internal 猫 ⽝犬 ⭕ Public ⭕ Internal 型の公開範囲より 小さくても準拠可能 ▶ 最大でも型の範囲まで ▶ 機能のアクセス範囲は 各プロトコル以上で プロトコルが internal 指定ならその機能は internal 以上
まとめ
クラス継承とプロトコル拡張は かなり性格が違う印象
性格の違いを意識して使うと 使い分けの仕方が見えてくるかも?
クラス継承とプロトコル拡張 ▶ クラス継承 ✴ 機能を特化して積み上げる ✴ 汎用性を意識した設計 ✴ 特徴を知るとは全てを知ること ✴ 常識を覆したときの影響範囲が広い? ▶ プロトコル拡張 ✴ 特徴で対象を説明する ✴ 特徴を意識した設計 ✴ 特徴が一目瞭然 ✴ 常識を覆すと新しいプロトコルが誕生?