如何在为继承的 属性 赋值之前委托给超类初始值设定项

How to delegate up to a superclass initializer before assigning a value to an inherited property

Swift documentation 在这里说关于初始化委托:

A designated initializer must delegate up to a superclass initializer before assigning a value to an inherited property. If it doesn’t, the new value the designated initializer assigns will be overwritten by the superclass as part of its own initialization.

让我们在下面的例子中说:

class Shape {
    var color: String
    
    init(color: String) {
        self.color = color
    }
}

class Circle: Shape {
    let pi = 3.14
    var r: Double
    
    init(r: Double, color: String) {
        self.r = r
        super.init(color: color)
    }
    
    func area() -> Double {
        return pi * r * r
    }
}

“在将值分配给继承的 属性 之前委托给超类初始值设定项”是什么意思?我的假设是“继承属性”是指子类新引入的属性none。

委托给超类初始化器 super.init(color: color) 的行为不就是为继承的 属性 赋值吗?我如何先分配给继承的属性,然后再委托给超类初始值设定项?超类初始值设定项覆盖新值的示例是什么?

您的示例实际上并不涉及在子类初始化程序中修改继承的 属性。继承的 属性 是由超类声明的 属性(例如您示例中的 color)。

那篇文档说,如果你想覆盖超级初始化器的行为并修改子类 init 中继承的 属性 的值,你首先需要调用 super.init 和只有这样你才能修改这个值。这是因为超类声明的所有值都将在 super.init.

中初始化

实际上,编译器甚至不允许您在调用 super.init 之前访问超类中声明的值,以避免文档中提到的错误。

检查下面的示例,其中超类将常量值分配给 id,而不管 init 的输入值是什么,而子类使用输入值并因此覆盖在超类中分配的值。

class Super {
    var id: Int

    init(id: Int) {
        self.id = 0
    }
}

class Sub: Super {
    let prop: String

    init(id: Int, prop: String) {
        self.prop = prop
        // The next line would actually result in the error: 'self' used in property access 'id' before 'super.init' call
        //self.id = id 
        super.init(id: id)
        self.id = id // this is where you can override a property declared by the superclass
    }
}

Sub(id: 2, prop: "") // id is correctly initialised to 2