Swfit-03.初始化器,可选链,协议。。。

2020-12-18  本文已影响0人  Fight_ing
tree_24.jpg
// 指定初始化器 
init(parameters) {
  statements 
}
// 便捷初始化器
convenience init(parameters) {
  statements 
}

每个类至少有一个指定初始化器,指定初始化器是类的主要初始化器
默认初始化器总是类的指定初始化器
类偏向于少量指定初始化器,一个类通常只有一个指定初始化器

初始化器的相互调用规则:
指定初始化器必须从它的直系父类调用指定初始化器
便捷初始化器必须从相同的类里调用另一个初始化器
便捷初始化器最终必须调用一个指定初始化器

class Person {
 var name: String
 init?(name: String) {
    if name.isEmpty { 
        return nil
    }
    self.name = name 
    }
}

1. 不允许同时定义参数标签、参数个数、参数类型相同的可失败初始化器和非可失败初始化器
2. 可以用init!定义隐式解包的可失败初始化器
3. 可失败初始化器可以调用非可失败初始化器,非可失败初始化器调用可失败初始化器需要进行解包
4. 如果初始化器调用一个可失败初始化器导致初始化失败,那么整个初始化过程都失败,并且之后的代码都停止执行 
5. 可以用一个非可失败初始化器重写一个可失败初始化器,但反过来是不行的
class Person {
    deinit {
        print("Person对象销毁了") 
    }
}
// deinit不接受任何参数,不能写小括号,不能自行调用 
// 父类的deinit能被子类继承
// 子类的deinit实现执行完毕后会调用父类的deinit
// 多个?可以链接在一起
// 如果链中任何一个节点是nil,那么整个链就会调用失败
var dog = person?.dog // Dog?
var weight = person?.dog.weight // Int? 
var price = person?.car?.price // Int?

class Person {
    var name: String = ""
    var dog: Dog = Dog()
    var car: Car? = Car()
    func age() -> Int { 18 }
    func eat() { print("Person eat") } 
    subscript(index: Int) -> Int { index }
}

var person: Person? = Person()

if let _ = person?.eat() { // ()? 
    print("eat调用成功")
} else { 
    print("eat调用失败")
}

person?.eat()默认没有返回值,也可以写成var p = person?eat()的赋值形式。因为在Swift中函数其实默认返回-> Void, 而Void = (),也就是空元祖。所以p也就是()?类型

// 协议中还可以定义初始化器init 
// 非final类实现时必须加上required
protocol Drawable {
    init(x: Int, y: Int)
}
class Point : Drawable {
    required init(x: Int, y: Int) {}
}
final class Size : Drawable {
    init(x: Int, y: Int) {}
}
// 如果从协议实现的初始化器,刚好是重写了父类的指定初始化器  
// 那么这个初始化必须同时加required、override
protocol Livable {
    init(age: Int)
}
class Person {
    init(age: Int) {}
}
class Student : Person, Livable {
    required override init(age: Int) {
        super.init(age: age) 
    }
}
// 让枚举遵守CaseIterable协议,可以实现遍历枚举值
enum Season : CaseIterable {
    case spring, summer, autumn, winter
}
let seasons = Season.allCases print(seasons.count) // 4 
for season in seasons {
    print(season)
} // spring summer autumn winter
class Person : CustomStringConvertible, CustomDebugStringConvertible { 
    var age = 0
    var description: String { "person_\(age)" }
    var debugDescription: String { "debug_person_\(age)" } 
}
var person = Person()
print(person) // person_0 
debugPrint(person) // debug_person_0

print调用的是CustomStringConvertible协议的description
debugPrint、po调用的是CustomDebugStringConvertible协议的debugDescription

上一篇 下一篇

猜你喜欢

热点阅读