基底クラスに処理の流れを記述し、実際の処理は派生クラスで記述したい事があると思います。
C++などの言語にはこの要求に応える為 抽象クラス(abstract class) という概念が用意されているのですが、Swiftには残念ながら抽象クラスは存在しません。
抽象クラスと同じ振る舞いをさせたい場合、protocolを利用することになります。
サンプルは次の要件で実装します。
- 基底クラス
BaseClass
に処理の流れを定義する - 基底クラスはインスタンス化を禁止する
- 処理の流れに使うメソッドはプロトコル
ClassFrameworkProtocol
に定義する - 派生クラス
SubClass
に実際の処理を記述する - 派生クラスは
ClassFrameworkProtocol
プロトコルを採用することを義務付ける
ClassFrameworkProtocol プロトコルの実装
protocol ClassFrameworkProtocol: class {
func a()
func b()
func c()
}
派生クラスで実装してもらいたいメソッド群を定義します。
基底クラスの実装
class BaseClass {
required init() {
assert(type(of: self) != BaseClass.self, "BaseClassはインスタンス化に対応していません")
assert(self is ClassFrameworkProtocol, "ClassFrameworkProtocolを採用する必用があります")
self.work()
}
func work() {
if let obj = self as? ClassFrameworkProtocol {
obj.a()
obj.b()
obj.c()
}
}
}
init()
に要件2と5を満たす為のチェックを記述しています。
work()
に処理の流れを記述しています。
派生クラスの実装
class SubClass: BaseClass {}
extension SubClass: ClassFrameworkProtocol {
func a() {
debugPrint(#function)
}
func b() {
debugPrint(#function)
}
func c() {
debugPrint(#function)
}
}
プロトコロル ClassFrameworkProtocol
を採用し、各メソッドの処理を記述しています。
実行結果
let obj = SubClass()
"a()"
"b()"
"c()"
要件2の検証
let baseObj = BaseClass()
assertion failed: BaseClassはインスタンス化に対応していません
要件5の検証
class NotAdoptedSubClass: BaseClass {}
let obj = NotAdoptedSubClass()
assertion failed: ClassFrameworkProtocolを採用する必用があります