iOS 的那些事儿

Swift中的required修饰符

2017-07-14  本文已影响1149人  silly鸿

required修饰符的使用规则

普通子类

在一般情况下,我们说到required修饰符,我们应该会想到的就是普通类(class)的init方法,比如这个类:

class MyClass{
var str: String?
init(str: String?) {
self.str = str
}
}

当我们定义MyClass的子类subClass并且实例化这个字类,我们一般会怎么做呢?我们通常情况下是这样子的:

class MyClass{
var str: String?
init(str: String?) {
self.str = str
}
}
class MySubClass: MyClass{
}
var MySubClass(str: "Hello Swift")

大家已经注意到了,在实例化MySubClass的过程中,其实是继承了MyClassinit初始化方法,接下来我们看看子类的初始化方法

子类的初始化方法

class MyClass{
var str: String?
init(str: String?) {
self.str = str
}
}
class MySubClass: MyClass{
override init(str: String?) {
super.init(str: str)
}
}
var MySubClass(str: "Hello Swift")

class MyClass{
var str: String?
init(str: String?) {
self.str = str
}
}
class MySubClass: MyClass{
init(i: Int) {
super.init(str: String(i))
}
}
var MySubClass(i: 123)

required修饰符

我们给父类的init()方法加上required修饰符后会发生什么呢,我们来看看:

class MyClass {
var str:String
required init(str:String) {
self.str = str
}
}
class MySubClass:MyClass
{
init(i:Int) {
super.init(str:String(i))
}
// 编译错误
}
MySubClass(i: 123)

如果你敲出上面的代码,OK,你百分之两百会报错,因为你没有实现父类中必须实现的方法,正确的写法
import Foundation

class MyClass{
var str: String?
required init(str: String?) {
self.str = str
}
}
class MySubClass: MyClass{
init(i: Int) {
super.init(str: String(i))
}

required init(str: String?) {
    fatalError("init(str:) has not been implemented")
}
}

var MySubClass(i: 123)

从上面的代码中,不难看出子类需要添加异于父类的初始化方法,必须要重写有required的修饰符的初始化方法,并且也要使用required修饰符而不是override,请千万注意!

如果子类中并没有不同于父类的初始化方法,Swift会默认使用父类的初始化方法

class MyClass{
var str: String?
required init(str: String?) {
self.str = str
}
}
class MySubClass: MyClass{
}
var MySubClass(str: "hello swift")

在这种情况下,编译器不会报错,因为如果子类没有任何初始化方法时,Swift会默认使用父类的初始化方法。在Apple的文档中也有相关描述:
You do not have to provide an explicit implementation of a required initializer if you can satisfy the requirement with an inherited initialiser.

上一篇下一篇

猜你喜欢

热点阅读