初期化子委譲とは、クラスのためにSwiftに組み込まれた初期化の委譲システムです。Swiftでは、指定初期化子(クラスのメイン初期化子で、すべてのプロパティの完全初期化を担当)と便利初期化子(さまざまなパラメータセットを使用してインスタンスを作成するのを補助する)との間に歴史的な違いがあります。
問題: クラスとそのサブクラス間で初期化子が無秩序に実行されると、基本クラスが完全に初期化されない、または初期化が1回以上行われる可能性があり、結果として無効なオブジェクトが生成されることがあります。
解決策は、厳格なルールです:
コード例:
class Vehicle { var wheels: Int // 指定初期化子 init(wheels: Int) { self.wheels = wheels } // 便利初期化子 convenience init() { self.init(wheels: 4) } } class Car: Vehicle { var color: String // 指定初期化子 init(wheels: Int, color: String) { self.color = color super.init(wheels: wheels) } // 便利初期化子 convenience init(color: String) { self.init(wheels: 4, color: color) } }
主な特徴:
質問 1: 便利初期化子はスーパークラスの初期化子を直接super.initで呼び出すことができますか?
いいえ、便利初期化子は常に現在のクラスの別の初期化子に初期化を委譲し、その後、スーパークラスの指定初期化子を呼び出すことができます。
質問 2: サブクラスで必須の初期化子を実装しなかった場合、どうなりますか?
スーパークラスに必須の初期化子がある場合は、各サブクラスで必ずオーバーライドする必要があります(requiredを使用)、さもなければコンパイラがエラーを出します。
質問 3: 便利初期化子と便利必須初期化子の違いは何ですか?
便利必須初期化子は、特定の便利初期化子がスーパークラスで必須として宣言されている場合、継承階層内での初期化をサポートするために必要です。
開発者が便利初期化子からsuper.initを呼び出しました。コードは特定の制約の不在によりコンパイルされましたが、実行時にエラーが発生しました:オブジェクトのすべてのプロパティが初期化されていませんでした。
利点:
欠点:
明確に構造化された指定初期化子と便利初期化子を使用し、相互に明示的に呼び出しました。ロジックはSwiftのルールに厳密に従って呼び出されたため、初期化は常に透明で正確でした。
利点:
欠点: