Swift プロトコルについてメモ
Swiftのプロトコルは型のインターフェースを定義するものです。
※インターフェース→二つのものを繋ぐ接点
インターフェースを定義し、抽象化することによって、複数のかたで共通の機能を実装することができる。
プロトコルはクラス、構造体、列挙体などで使われ、プロトコルのインターフェースを満たす型は、”プロトコルに準拠している”と言われる。
こちらより
プロトコルの定義方法
protocol プロトコル名 {}
protocol CurryProtocal {
func makeCurry()
}
このようにすることでCurryProtocalというprotocolを定義できました。
クラスでの準拠
class Chef:CurryProtocal {
func makeCurry() {
print("カリーを作ります")
}
}
let chef = Chef()
chef.makeCurry()//カリーを作ります
構造体での準拠
struct indiaChef:CurryProtocal {
func makeCurry() {
print("インディアカリーを作ります")
}
}
let indiaChef = makeCurry()
indiaChef.makeCurry()//インディアカリーを作ります
クラスと構造体の両方を使用する例
let cooks: [CurryProtocal] = [Chef,indiaChef]
for cook in cooks {
cook.makeCurry)()
}
// "カリーを作ります"
// "インディアカリーを作ります"
プロトコルのプロパティ要件とメソッド要件
protocol CurryProtocol {
// プロパティ要件
var kuminpaudar: Int { get set }
var onionsurais: Int { get }
// メソッド要件
func someMethod() -> String
}
プロパティ要件のget set部分について
{ get set } → 読み取りと書き込みが可能でなければならない
{ get } → 読み取りができればいい
func someMethod() -> String
someMethod: 引数を取らずに String型を返すメソッドです。
※読み取り(get)
プロパティの値を取得することを 読み取り(get)という、プロパティが読み取り可能であるということは、そのプロパティの値を外部から取得できるということ。
※書き込み(set)
プロパティの値を設定することを書き込み(set)という。プロパティが書き込み可能であるということは、そのプロパテきの値を外部から設定できることを意味する。
プロトコルの適合
クラス、構造体、列挙型がプロトコルに適合(confrom)するためには、そのプロトコルが要求するプロパティやメソッドを実装する必要がある。
例
protocol SomeProtocol {
//プロパティ要件
var mustBeSettable: Int {get set}
var doesNotNeedToBeSettable: Int {get}
//メソッド要件
func someMethod() -> String
↓↓↓↓↓ プロトコルに適合(confrom)するために、プロパティとメソッドを実装
struct SomeStructure: SomeProtocol {
var mustBeSettable: Int
var doesNotNeedToBeSettable: Int
func someMethod() -> String {
return "Hello"
}
}
SomeProtocolに準拠したSomeStructure struct
デリゲートパターン
あるオブジェクトが別のオブジェクトに対してタスクを委譲するパターン
protocol CurryDelegate {
func CurryMake(result: String)
}
class IndiaChef {
var delegate: CurryDelegate?
func makingCurry() {
// カリー作り実行
let result = "カリー作り完了"
delegate?.CurryMake(result: result)
}
}
class CurryHandler: CurryDelegate {
func CurryMake(result: String) {
print(result)
}
}
let indiaChef = IndiaChef()
let handler = CurryHandler()
indiaChef.delegate = handler
indiaChef.makingCurry() // "カリー作り完了" と出力されます
というデータの流れ
IndiaChef makingCurry デリゲートに準拠したIndiaChefクラス
↓
CurryDelegate CurryMake CurryDelegateプロトコル
↓
CurryHandler CurryMake デリゲートに準拠したCurryHandlerクラス
プロトコルの拡張
プロトコルは拡張(extension)を利用してデフォルト実装を提供することができる。これにより、すべての適合タイプに共通の動作を提供することができる。
extension SomeProtocol {
func someMethod() -> String {
return "Default Impkementation"
}
}
ここで覚えておくことは、
プロトコルは、異なる型間で共通の機能を持たせたり
デリゲートパターンを使用して、クラス間の通信を実現したりできる。
Discussion