初期化2

Swift programming language の Initialization の章が分かりにくいので、初期化2に簡単にまとめます。

イニシャライザー

// 最も簡単なイニシャライザー
    class Animal {
        var name: String = ""
        var nakigoe: String = ""
        init() {
        }
    }

// init でプロパティ値を初期化
    class Animal {
        var name: String
        var nakigoe: String
        init() {
            name = ""
            nakigoe = ""
        }
    }

// initの書式
//  init(ラベル名 引数名: 型) { 式 }
  let animal = Animal(animalName: "animal")

    class Animal {
        var name: String
        var nakigoe: String?
        init(animalName name: String) {
            self.name = name
        }
    }

// 引数ラベルのない初期化パラメーター
  let animal = Animal("animal")

    class Animal {
        var name: String
        var nakigoe: String?
        init(_ name: String) {
            self.name = name
        }
    }

// すべてのプロパティのデフォルト値が提供されている場合、initは省略できる
// nakigoeは、オプショナルString のため、デフォルト値 nil が与えられる
    class Animal {
        var name: String = ""
        var nakigoe: String?
    }
    
// メンバーの初期化例
  let animal = Animal(name: "animal", nakigoe: nil)

    class Animal {
        var name: String = ""
        var nakigoe: String? = nil
        init(name: String, nakigoe: String?) {
            self.name = name
            self.nakigoe = nakigoe
        }
    }

指定イニシャライザとコンビニエンスイニシャライザ

// 指定イニシャライザ
// すべてのクラスには、少なくとも1つの指定イニシャライザが必要
init(parameters) {
    statements
}

// コンビニエンスイニシャライザは二次的なもの
// クラスのイニシャライザをサポートする
convenience init(parameters) {
    statements
}
  • ルール1 指定イニシャライザは、直接のスーパークラスから指定イニシャライザを呼び出す必要があります。
  • ルール2 コンビニエンスイニシャライザは、同じクラスから別のイニシャライザを呼び出す必要があります。
  • ルール3 コンビニエンスイニシャライザは、最終的に指定イニシャライザを呼び出す必要があります。
../_images/initializerDelegation01_2x.png
    class Animal {
        var name: String
        var nakigoe: String?
        // 指定イニシャライザー
        init(_ name: String) {
            self.name = name
        }
        // コンビニエンスイニシャライザー
        convenience init(name: String, nakigoe: String)
        {
            self.init(name)
            self.nakigoe = nakigoe
        }
        func naku(){
            print(nakigoe ?? "")
        }
    }
// スーパークラス内のコンビニエンスイニシャライザー
        convenience init(name: String, nakigoe: String)

// サブクラスからスーパークラスのコンビニエンスイニシャライザーを
// オーバーライドしようとすると、次のエラーが発生する
        override convenience init(name: String, nakigoe: String)
// Initializer does not override a designated initializer from its superclass

2フェーズ初期化

フェーズ1では、すべての格納プロパティに初期値が割り当てられます。
フェーズ2では、各クラスに格納されたプロパティをカスタマイズできる。

    class Animal {
        var name: String
        var nakigoe: String?
        init(_ name: String) {
            self.name = name
        }
        convenience init(name: String, nakigoe: String)
        {
            self.init(name)
            self.nakigoe = nakigoe
        }
        func naku(){
            print(nakigoe ?? "")
        }
    }

    class Dog: Animal {
        override init(_ name: String) {
            // フェーズ1  スーパークラスのイニシャライザーを呼ぶ必要がある
            super.init(name)
            // フェーズ2 カスタマイズできる
            self.nakigoe = "wanwan" 
        }
    }

// super.init を呼ばないと、次のエラーになる
// 'self' used in property access 'nakigoe' before 'super.init' call
// 'super.init' isn't called on all paths before returning from initializer

自動的なイニシャライザの継承

// ルール1
// サブクラスが指定イニシャライザを定義していない場合、
// 自動的に Animal のinit が継承される
   class Animal {
        var name: String
        var nakigoe: String?
        init(_ name: String) {
            self.name = name
            self.nakigoe = "designated wanwan"
        }
        convenience init(name: String, nakigoe: String)
        {
            self.init(name)
            self.nakigoe = "convinience wanwa"
        }
        func naku(){
            print(nakigoe ?? "")
        }
    }

    class Dog: Animal {
        // サブクラスが指定イニシャライザを定義していない場合、
        // 自動的に Animal のinit が継承される
    }

//         let dog = Dog("Snoopy")
//        dog.naku()
// 結果: designated wanwan
// ルール2
// サブクラスがすべてのスーパークラスの指定イニシャライザの実装を提供する場合
// スーパークラスのすべてのコンビニエンスイニシャライザを自動的に継承する
    class Animal {
        var name: String
        var nakigoe: String?
        init(_ name: String) {
            self.name = name
            self.nakigoe = "designated wanwan"
        }
        convenience init(name: String, nakigoe: String)
        {
            self.init(name)
            self.nakigoe = nakigoe
        }
        func naku(){
            print(nakigoe ?? "")
        }
    }

    class Dog: Animal {
        override init(_ name: String) {
            super.init(name)
            self.name = name
            self.nakigoe = "designated wanwan"
        }
    }

//        let dog = Dog(name: "Snoopy", nakigoe: "superclass's convinience init wanwan")
//       dog.naku()
// 結果: superclass's convinience init wanwan

失敗可能なイニシャライザ

失敗可能なイニシャライザは、初期化する型のオプションの値を作成します。失敗可能なイニシャライザ内に return nil を書き込んで、初期化の失敗をトリガーします。

        if let animal = Animal("")
        {
            // 初期化に失敗して、animal はnil になるため、次の行は実行されない
            animal.naku()
        }
    
    class Animal {
        var name: String
        var nakigoe: String?
        // 失敗可能なイニシャライザ
        init?(_ name: String?) {
            if name == "" {
                // return nil で初期化に失敗したことをトリガーする
                return nil
            }
            self.name = name!
            self.nakigoe = "designated wanwan"
        }
        func naku(){
            print(nakigoe ?? "")
        }
    }

クラス、構造体、または列挙体の失敗可能なイニシャライザは、同じクラス、構造体、または列挙体から別の失敗可能なイニシャライザに委任できます。

サブクラスでスーパークラスの失敗可能なイニシャライザをオーバーライドできます。また、スーパークラスの初期化に失敗しても、初期化に失敗しないサブクラスでオーバーライドできます。

init!失敗可能なイニシャライザ

暗黙的にアンラップされたオプションのインスタンスを作成する、失敗可能なイニシャライザ init! を定義できます。

        if let animal = Animal("")
        {
            animal.naku()
        }
    
    class Animal {
        var name: String
        var nakigoe: String?
        init!(_ name: String?) {
            if name == "" {
                self.name = "default name"
            }
            self.name = name!
            self.nakigoe = "designated wanwan"
        }
        func naku(){
            print(nakigoe ?? "")
        }
    }

必須イニシャライザ

    class Animal {
        var name: String
        var nakigoe: String?
        // すべてのサブクラスがそのイニシャライザを実装する必要があることを示す
        required init(name: String) {
            self.name = name
            self.nakigoe = "wanwan"
        }
    }

    class Dog: Animal {
        // override は不要
        required init(name: String)
        {
            super.init(name: name)
            self.name = "dog: " + name
        }

投稿者: admin

Free Software Engineer

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です