一尘不染

为什么在Swift类中使用必需的初始化器?

swift

我试图了解requiredSwift类中关键字的使用。

class SomeClass 
{
    required init() {
        // initializer implementation goes here
    }
}

required不会强迫我在子类中实现该方法。如果我要重写required指定初始化我的父类的我需要写required和不override。我知道它是如何工作的,但不明白为什么我应该这样做。

有什么好处required?据我所知,像C#这样的语言没有这样的东西,并且可以很好地工作override


阅读 207

收藏
2020-07-07

共1个答案

一尘不染

实际上,这只是使编译器满意的一种方法,可以确保该类如果具有任何子类,它们将继承或实现相同的初始化程序。在这一点上存在疑问,因为这样的规则:
如果子类具有自己的指定初始化程序,则不会继承超类的初始化程序 。因此,超类可能有一个初始化器,而子类可能 没有
它。required克服了这种可能性。

需要以这种方式满足编译器的一种情况是协议,其工作方式如下:

protocol Flier {
    init()
}
class Bird: Flier {
    init() {} // compile error
}

问题是,如果Bird有一个子类,则该子类将必须实现或继承init,而您不能保证做到这一点。标记鸟initrequired不保证它。

另外,您可以将Bird标记为final,从而保证相反,即它永远不会有子类。

另一种情况是您拥有一个工厂方法,该方法可以通过调用相同的初始化程序来构成一个类或其子类:

class Dog {
    var name: String
    init(name: String) {
        self.name = name
    }
}

class NoisyDog: Dog {

}

func dogMakerAndNamer(whattype: Dog.Type) -> Dog {
    let d = whattype.init(name: "Fido") // compile error
    return d
}

dogMakerAndNamer``init(name:)在Dog或Dog子类上调用初始化程序。但是,编译器如何确保子类具有init(name:)初始化程序?该required名称可以减轻编译器的恐惧。

2020-07-07