为什么在 Swift 类中使用必需的初始化器? [英] Why use required Initializers in Swift classes?

查看:26
本文介绍了为什么在 Swift 类中使用必需的初始化器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试了解 required 关键字在 Swift 类中的使用.

I am trying to understand the use of the required keyword in Swift classes.

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

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

required doesn't force me to implement the method in my child-class. If I want to override the required designated initializer of my parent class I need to write required and not override. I know how it works but can not understand why I should do this.

必需有什么好处?据我所知,像 C# 这样的语言没有这样的东西,并且与 override 一起工作得很好.

What is the benefit of required? As far as I can tell, languages like C# don't have something like this and work just fine with override.

推荐答案

这实际上只是满足编译器的一种方式,以确保如果这个类有任何子类,它们将继承或实现相同的初始化程序.这点值得怀疑,因为如果子类有自己的指定初始化程序,则不会继承超类的初始化程序.因此,超类有可能有一个初始化器,而子类没有有它.required 克服了这种可能性.

It's actually just a way of satisfying the compiler to assure it that if this class were to have any subclasses, they would inherit or implement this same initializer. There is doubt on this point, because of the rule that if a subclass has a designated initializer of its own, no initializers from the superclass are inherited. Thus it is possible for a superclass to have an initializer and the subclass not to have it. required overcomes that possibility.

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

One situation where the compiler needs to be satisfied in this way involves protocols, and works like this:

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

问题在于,如果 Bird 有一个子类,则该子类必须实现或继承 init,而您不能保证这一点.将 Bird 的 init 标记为 required 确实可以保证这一点.

The problem is that if Bird had a subclass, that subclass would have to implement or inherit init, and you have not guaranteed that. Marking Bird's init as required does guarantee it.

或者,您可以将 Bird 标记为 final,从而保证反过来,即它永远不会有子类.

Alternatively, you could mark Bird as final, thus guaranteeing the converse, namely that it will never have a subclass.

另一种情况是你有一个工厂方法,它可以通过调用相同的初始化程序来创建一个类或其子类:

Another situation is where you have a factory method that can make a class or its subclass by calling the same initializer:

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 正在调用 Dog 或 Dog 子类的 init(name:) 初始化程序.但是编译器如何确定一个子类会有一个 init(name:) 初始化器呢?required 名称可以安抚编译器的恐惧.

dogMakerAndNamer is calling the init(name:) initializer on Dog or a Dog subclass. But how can the compiler be sure that a subclass will have an init(name:) initializer? The required designation calms the compiler's fears.

这篇关于为什么在 Swift 类中使用必需的初始化器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆