Swift Initializer之谜

时间:2017-10-04 06:02:11

标签: ios swift xcode initializer

几个代码块:

这有效:

import Foundation

class Class1 {
    init(param1: String?) {
        print("hello")
    }

    convenience init() {
        self.init(param1: nil)
    }
}

class SubClass1: Class1 {

}

let obj = SubClass1()

在上面的代码中,指定的初始化程序向下传递给SubClass1,因为SubClass1不提供自己的指定初始化程序。此外,便利初始化也传承下来。因此,这有效。

import Foundation

class Class1 {
    init(param1: String?) {
        print("hello")
    }

    convenience init() {
        self.init(param1: nil)
    }
}

class SubClass1: Class1 {
    override init(param1: String?) {
        print("hello 2")
        super.init(param1: nil)
    }
}

let obj = SubClass1()

这也有效,因为SubClass1现在提供了自己的指定初始化器。

import Foundation

class Class1 {
    init(param1: String?) {
        print("hello")
    }

    init(param2: String?) {
        print("world")
    }

    convenience init() {
        self.init(param1: nil)
    }
}

class SubClass1: Class1 {
    override init(param1: String?) {
        print("hello 2")
        super.init(param1: nil)
    }
}

let obj = SubClass1()

这给出了“错误:在调用中缺少参数'param1'的参数”,用于最后一行。 这里有一个SubClass1的指定初始化程序,而来自parent的便捷初始化程序也调用相同的初始化程序,那么为什么会出错?

import Foundation

class Class1 {
    init(param1: String?) {
        print("hello")
    }

    required init(param2: String?) {
        print("world")
    }

    convenience init() {
        self.init(param1: nil)
    }
}

class SubClass1: Class1 {
    override init(param1: String?) {
        print("hello 2")
        super.init(param1: nil)
    }

    required init(param2: String?) {
        print("world")
        super.init(param2: nil)
    }
}

let obj = SubClass1()

这有效:

import Foundation

class Class1 {
    init(param1: String?) {
        print("hello")
    }

    init(param2: String?) {
        print("world")
    }

    convenience init() {
        self.init(param1: nil)
    }
}

class SubClass1: Class1 {
    override init(param1: String?) {
        print("hello 2")
        super.init(param1: nil)
    }

    override init(param2: String?) {
        print("world")
        super.init(param2: nil)
    }
}

let obj = SubClass1()

为什么需要覆盖所有指定的初始化程序才能使一个便捷初始化程序只能调用其中一个指定的初始化程序?

1 个答案:

答案 0 :(得分:1)

swift guide中明确说明了此行为。

  

假设您为任何新属性提供默认值   在子类中引入,适用以下两个规则:

     

规则1 如果您的子类未定义任何指定的初始值设定项,则为   自动继承其所有超类指定的初始化器。

     

规则2 如果您的子类提供了 所有 的实现   超类指定初始化程序 - 通过按照继承它们   规则1,或通过提供自定义实现作为其一部分   定义 - 然后它自动继承所有的超类   便利初始化者。

所以基本上,你的子类必须覆盖/定义所有超类'指定的初始化器,以便继承超级类'便利初始化者。