Edited at

[Swift] convenienceイニシャライザとdesignated(指定)イニシャライザ

More than 5 years have passed since last update.

iBooksのSwift本を読んでいて、convenience initializerというのを見つけました。

また対比として、designated initializerという単語が出てきます。

要は指定イニシャライザです。

ちょっと文章とか曖昧なので、違ったら突っ込んでもらいたいんですが、convenience initializerは他のイニシャライザに処理を委譲(delegate)することができます。

つまりイニシャライザの中で別のイニシャライザを呼ぶことが出来ます。


sample.swift

class SomeClass {

var name: String
init(name: String) {
self.name = name
}
convenience init() {
self.init(name: "default name")
}
}

var aClass: SomeClass = SomeClass() // => "name: default name"


convenienceの名前通り、デフォルトの処理があって、基本はそれに任せつつ、必要があれば引数を取って特別に処理をする、みたいなことを想定しているのでしょうか。


Super classを含めたイニシャライザ

上の例だけならなるほど、で終わりだったんですが、継承を含めるとさらに複雑になります。

サブクラスのイニシャライザ内で、Super classで定義された変数にアクセスする場合は、まず最初にsuper.initを呼ばないとなりません。(Super classのイニシャライザを呼んでからならアクセスできる)

さらにこのsuper.initを呼ぶ際、designated initializerを呼び出す必要があります。

(つまり、convenience initializerは呼べない)


ok.swift

class SubClass: SomeClass2 {

var hoge: String
init() {
self.hoge = "foo" // Sub classで定義されている変数には`super.init`前にアクセス可能
super.init(name: "hogehoge") // Super classのdesignated initializerは`init(name:)`
self.name = "name" // Super classのinitializerを呼んだ後ならアクセスできる
}
}


ng.swift

class SubClass: SomeClass2 {

init() {
self.name = "name" // `super.init`前に、Super classの変数にはアクセスできない
super.init() // `convenience initializer`はSub classから直接呼べない
}
}