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

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

问题描述

我试图了解Swift类中required关键字的使用.

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.

required有什么好处? 据我所知,像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.

推荐答案

实际上,这只是使编译器满意的一种方式,以确保如果此类具有任何子类,它们将继承或实现相同的初始化程序.在这一点上存在疑问,因为如果子类具有自己的指定初始化程序,则不会继承超类的初始化程序.因此,超类可能具有初始化器,而子类 not 可能具有初始化器. 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天全站免登陆