LoginSignup
6
4

More than 5 years have passed since last update.

SwiftでMixinを実現する

Posted at

継承あまり使いたくないけど、同じメソッドを異なるクラスで使えるようにしたいことがある。
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に準拠するクラスの方でも用意してあげれば良い。
便利。

6
4
1

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
6
4