この記事では「The Swift Programming Language」を1から読んだ感想とか発見を書いてみようと思います。
「The Swift Programming Language」とはSwiftの公式ドキュメントでiBooksや下ページで見る事ができます。
The Swift Programming Language (Swift 2.1): About Swift
読んだ所
今回はInitialization
という項目を読みました。
The Swift Programming Language (Swift 2.1): Initialization
学んだこと
パラメータなしのInitializer
_を最初につければパラメータの指定が不要です。
class SuperClass { init(_ value: Double) { } } SuperClass(1)
デフォルトInitializer
initializerが定義されていない場合はSuperClass()
という形で初期化できます。
class SuperClass {
}
SuperClass()
Designated InitializersとConvenience Initializers
Designated Initializers
が通常のInitializerでConvenience
は下のように書くInitializerです。
convenience init(value: String) { self.init(value: Double(value) ?? 0) }
2種類のInitializerは下のルールが適用されるようです。
- A designated initializer must call a designated initializer from its immediate superclass.
- A convenience initializer must call another initializer from the same class.
- A convenience initializer must ultimately call a designated initializer.
A designated initializer must call a designated initializer from its immediate superclass.
designated initializer
は親クラスのdesignated initializer
を呼び出す必要があるようです。
下のサンプルではsuper.init(intValue: 1)
を呼ばないとエラーになりました。
class SuperClass { init(intValue: Int) {} } class SubClass: SuperClass { var value: Double? init(value: Double) { super.init(intValue: 1) self.value = value } }
親クラスがdesignated initializer
を持っていなければ呼ぶ必要がないです。
class SuperClass { } class SubClass: SuperClass { var value: Double? init(value: Double) { self.value = value } }
A convenience initializer must call another initializer from the same class.
convenience initializer
は同じクラスのInitializerを呼ばなければいけません。
class SubClass: SuperClass { var value: Double? init(value: Double) { self.value = value super.init(value: 1) } convenience init() { self.init(value: 1) // self.initを呼ばないとエラー } }
自分以外のInitializerがない時はデフォルトのInitializerを呼ぶ必要があります。
class SubClass: SuperClass { var value: Double? convenience init() { self.init() } }
親クラスのInitializerを呼ぼうとするとエラーです。
class SubClass: SuperClass { var value: Double? convenience init() { super.init() // これはエラー } }
逆にdesignated initializer
は同じクラスのInitializerを呼べません。
A convenience initializer must ultimately call a designated initializer.
convenience initializer
は最終的にdesignated initializer
を呼ぶ必要があります。
呼び出し先がdesignated initializer
を呼んでいるならconvenience initializer
からconvenience initializer
を呼び出す事もできるという事です。
class SubClass: SuperClass { var value: Double? init(value: Double) { self.value = value super.init(value: 1) } convenience init(value1: Double) { self.init(value: 1) } convenience init(value2: Double) { self.init(value1: 1) } }
OptionalなInitializer
下のように条件によってnilを返すInitializerも定義できます。
class SuperClass { init?(value: Double) { if value == 0 { return nil } } }
init!
はImplicitlyUnwrappedOptional型の変数を返します。
class SuperClass { init!(value: Double) { if value == 0 { return nil } } }
required
requiredを付けられたInitializerはサブクラスでオーバーライドしなければいけません。
class SuperClass { var value: Int required init(value: Int) { self.value = value } } class SubClass: SuperClass { required init(value: Int) { super.init(value: value) } init(value1: Int) { super.init(value: value1) } }
Initializerが1件もない場合はrequired
なInitializerをオーバーライドする必要はありません。
class SuperClass { var value: Int required init(value: Int) { self.value = value } } class SubClass: SuperClass { }
クロージャーを使ったプロパティーの初期化
Initializerと少し話題がそれますが、プロパティーの初期化は下のようにクロージャーを使えます。
class SuperClass { var value: Int = { return 1 }() }