
class Person {
required init() {
}
init(age:Int) {
}
}
class subPerson : Person{
init(gender:Int) {
super.init(age: 0)
}
required init() {
super.init()
}
}
被required修饰的,在子类中,也是必须要实现的,但是如果subPerson不写任何指定初始化器,那么就会自动继承那个Required init()方法,也不会报错的,如下面代码
class Person {
required init() {
}
init(age:Int) {
}
}
class subPerson : Person{
// init(gender:Int) {
// super.init(age: 0)
//
// }
//
// required init() {
// super.init()
// }
}
但是只要指定了初始化器,就必须实现required修饰的方法。
属性观察器
父类的属性在它自己的初始化器中赋值,是不会触发属性观察器的,但在子类的初始化器中赋值,会出发属性观察器

可失败初始化器
类、结构体、枚举可以使用init?定义可失败初始化器
class Person {
var name:String
init?(name:String) {
if name.isEmpty {
return nil
}
self.name = name
}
}
这段代码的意思是,创建person对象可能失败,如果我传入的name是个空,则会返回一个可选类型,因为只有可选类型才能为空
示例
var num = Int("123")
public init?(_ description: String)
enum Answer : Int {
case wrong,right
}
var an = Answer(rawValue:1)
不允许同时定义参数标签,参数个数,参数类型相同的可失败初始化器和非可失败初始化器
class Person {
var name:String
init?(name:String) {
if name.isEmpty {
return nil
}
self.name = name
}
init(name:String) {
self.name = name
}
}
在上述代码中,两个init的参数这些都是一样的,但一个是可失败,一个是非失败的,这样是不允许的
反初始化器 - deinit
deinit叫做反初始化器,类似于C++的析构函数、OC的dealloc方法
当类的实例对象被释放内存的时候,就会调用实例对象的deinit方法
class Person {
deinit {
}
}
1.父类的deinit能被子类继承
2.子类的deinit实现执行完毕后会调用父类的deinit
可选链
class Person {
var name:String = ""
var dog:Dog = Dog()
var car:Car? = Car()
func age() -> Int { 18 }
func eat() { print("Person eat") }
subscript(index i:Int) -> Int {
return i
}
}
上述代码中,我们定义了一个Person类,接下来我们创建一个Person类
var person:Person? = Person() //定义了一个可选Person类
var age1 = person!.age() // 强制结包 Int
var age2 = person?.age() // Int?返回可选项,如果person为空,那么不会去调用ag()这个方法
var name = person?.name // String?
var index = person?[6] // Int?
func getName() -> String { "jack" }
// 如果person是nil,不会调用getName()
person?.name = getName()
var dog = person?.dog // Dog?
var weight = person?.dog.weight // Int? 在这里我们可以看出,最后得到的weight也是可选的
//weight可选的属性,从person?这里像个链条一样,带给了后面的属性
var price = person?.car?.price // Int? 这里需要注意,因为我们在定义Person这个类的时候
//car变量是可选性的,那么我们在点出car这个成员属性时,也是需要加上❓的
如果链中任何一个节点是nil,那么整个链就会调用失败
可以得出几点总结
1.如果可选项为nil,调用方法、下标、属性就会失败,结果为nil
2.如果可选项不为nil,调用方法、下标、属性成功,结果会被包装成可选项
3.如果结果本来就是可选项,不会进行再次包装
网友评论