Protocol
mixin
Swift2.0

SwiftでMixinを実現する

More than 3 years have passed since last update.

継承あまり使いたくないけど、同じメソッドを異なるクラスで使えるようにしたいことがある。

RubyではMixinという機能が提供されており、簡単に実現できる。

Swiftでも、Swift2.0で追加されたprotocol拡張を使うと、Mixinを実現できる。

protocolにextensionを作ってあげると、メソッドのデフォルト挙動を設定することができる。

protocol DogStyle {

func bow()
}

extension DogStyle {
func bow() {
print("bow wow!!")
}
}

class Human: DogStyle {
}

class Fish: DogStyle {
}

let kenji = Human()
kenji.bow() //"bow wow!!"

let iwana = Fish()
iwana.bow() //"bow wow!!"

上の例だと、DogStyle protocolをくっつけてやると、HumanもFishもbow()が使えるようになる。

インスタンス変数にアクセスするようなメソッドでも、protocolに変数の定義を書いてあげれば使えるようになる。

protocol DogStyle {

func bow()
}

extension DogStyle {
func bow() {
print("bow wow!!")
}
}

protocol CatStyle {
var times: Int { get set }
func meow()
}

extension CatStyle {
func meow() {
for _ in 0..<times {
print("mew meow!!")
}
}
}

class Human: DogStyle, CatStyle {
var times: Int
init(times: Int) {
self.times = times
}
}

class Fish: DogStyle, CatStyle {
var times: Int
init(times: Int) {
self.times = times
}
}

let kenji = Human(times: 5)
kenji.bow()
kenji.meow()

let iwana = Fish(times: 10)
iwana.bow()
iwana.meow()

上の例だと、CatStyle protocolのmeow()メソッドは、変数timesを参照している。

その場合も、protocol内で変数timesを定義してあげて、protocolに準拠するクラスの方でも用意してあげれば良い。

便利。