しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

Swift2.0で追加されたprotocol extensionsを試してみる

Swift2.0で追加されたprotocol extensionsを試してみたのでそのメモです。

protocol extensionsとは

プロトコルメソッドを追加できる機能です。
下のようにextensionを使ってprotocolメソッドを追加します。

protocol MyProtocol {
    func aaa()
}
extension MyProtocol {
    func bbb() { print("AAA") }
}

protocolとは

Javaで言うInterfaceです。
下のようにメソッドの宣言をして利用します。

protocol MyProtocol {
    func aaa()
}

protocol extensionsの使い方

先ほど書いた通りextensionを使ってメソッドの追加をします。

protocol MyProtocol {}
extension MyProtocol {
    func aaa() { print("AAA") }
}
class MyClass: MyProtocol {}

MyClass().aaa()

protocolに直接メソッドを追加する事はできません。
メソッドの定義はextension中で行う必要があります。

protocol MyProtocol {
    func aaa() { print("AAA") } // これはエラーになる
}

extension中は逆に宣言だけする事はできません。

protocol MyProtocol {}
extension MyProtocol {
    func ccc() // これもエラー
}

extensionなのでインスタンス変数の定義もできません。

protocol MyProtocol {}
extension MyProtocol {
    var a: Int? // これもエラー
}

protocol中で宣言したメソッドextensionsで実装する事もできます。
そうするとクラス中でメソッドの実装をする必要がなくなります。

protocol MyProtocol {
    func aaa()
}
extension MyProtocol {
    func aaa() { print(222) }
}
class MyClass: MyProtocol {} // aaaの実装を書かなくて良い

MyClass().aaa()

クラス中で実装すれば、そちらが呼ばれます。

protocol MyProtocol {
    func aaa()
}
extension MyProtocol {
    func aaa() { print(222) } // これは呼ばれない
}
class MyClass: MyProtocol {
    func aaa() { print(111) } // こっちが呼ばれる
}

MyClass().aaa()

UITableViewDataSourceのようなUIKitのプロトコルを拡張する事もできました。

import Foundation
import UIKit

extension UITableViewDataSource {
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
}

classの中からextensionの実装を呼ぶ方法は見つかりませんでした。

protocol MyProtocol {
    func aaa()
}
extension MyProtocol {
    func aaa() { print(222) }
}
class MyClass: MyProtocol {
    func aaa() { super.aaa() } // これはエラー
}