目录
required的用法
/// 一、required的用法
func requiredUse() -> Void {
/**
用required修饰指定初始化器,表明其所有子类必须都实现该初始化器(通过继承或重写)
如果子类重写该初始化器必须加上required,不用加override
*/
class Person{
var age:Int
var score:Int{
willSet{
print("willSet",newValue)
}
didSet{
print("didSet",oldValue)
}
}
required init() {
self.age = 0
self.score = 0
}
init(age:Int,score:Int) {
self.age = age
self.score = score
}
convenience init(age:Int){
self.init(age:age,score:0)
}
convenience init(score:Int){
self.init(age:0,score:score)
}
}
//通过继承方式实现
class Student:Person{
}
//通过重写方式实现
class Teacher:Person{
required init() {
super.init()
self.age = 22
self.score = 90
}
}
let teacher = Teacher()
print(teacher)
}
属性观察器
//二、属性观察器
func properObserver(){
/**
父类的属性在它自己的初始化器中赋值不会触发属性观察器
但在子类的初始化器中赋值会触发属性观察器
*/
class Person {
var age:Int = 0{
willSet{
print("Person willSet")
}
didSet{
print("Person didSet")
}
}
var name:String = ""
init(age:Int,name:String){
self.age = age
self.name = name
}
convenience init(){
self.init(age:0,name:"")
}
}
class Student: Person {
var score:Int
init(score:Int){
self.score = score
super.init(age: 0, name: "")
self.age = 7
}
convenience init(){
self.init(score:0)
}
}
let stu = Student()
print(stu.age)
}
可失败初始化器
///三、可失败初始化器
func initializerFail() -> Void {
/**
类、结构体、枚举都可以使用init?定义可失败初始化器
之前接触过的可失败初始化器
var num = Int("123")
public init?(_ description: String)
enum Answer : Int {
case wrong, right
}
var an = Answer(rawValue: 1)
不允许同时定义参数标签、参数个数、参数类型相同的可失败初始化器和非可失败初始化器
可以用init!定义隐式解包的可失败初始化器
可失败初始化器可以调用非可失败初始化器,非可失败初始化器调用可失败初始化器需要进行解包
如果初始化器调用一个可失败初始化器导致初始化失败,那么整个初始化过程都失败,并且之后的代码都停止执行
可以用一个非可失败初始化器重写一个可失败初始化器,但反过来是不行的
*/
//1、可失败初始化器
do{
print("--------1---------")
let num = Int("123")
print("num= ",num!)
class Person {
var name:String
//返回的是一个可选项
init?(name:String){
if name.isEmpty {
return nil
}
self.name = name
}
}
let per = Person(name: "")
print(per)//per是可选项 nil
let person = Person(name:"tom")
print(person?.name)//Optional("g")
print((person?.name)!)//g
print(person!.name)//g
}
//2、可失败初始化器 隐试解包
do{
print("--------2--------")
let num :Int! = 10
print("num = ",num)//num为可选项
//num为可选项 但num+7中num会自动解包
print("num + 7 = ",num+7)
class Person {
var name:String
init!(name:String){
if name.isEmpty {
return nil
}
self.name = name
}
}
let per = Person(name: "")
print(per)//per是可选项 nil
let per1 = Person(name: "tom")
print(per1!.name)//per1是可选项 tom
}
//3、调用可失败初始化器
do{
print("--------3----------")
class Person{
var name:String
init?(name:String) {
if name.isEmpty {
return nil
}
self.name = name
}
convenience init(){
//非可失败初始化器调用可失败初始化器需要进行解包
self.init(name:"tom")!
}
}
let person1 = Person(name: "")
print(person1)//nil
let person2 = Person(name: "Jack")
print(person2)//可选项
print(person2!.name)
let person3 = Person()
print(person3)//person对象
print(person3.name)
}
//4、调用可失败初始化器
do{
print("--------4----------")
class Person {
var name:String
init!(name:String){
if name.isEmpty {
return nil
}
self.name = name
}
convenience init(){
//可自动解包
self.init(name:"tom")
}
}
let per1 = Person(name:"")
print(per1)//nil
let per2 = Person(name: "jack")
print(per2)//可选项
print(per2!.name)//jack
let per3 = Person()
print(per3)//person 对象
print(per3.name)//tom
}
}
反初始化器调用
/// 四、反初始化器调用
func deinitUse() -> Void {
//1、deinit函数调用
do{
/**
deinit相当于oc的delloc c++的析构函数
*/
print("------1------")
class Person {
var name:String
init(name:String){
self.name = name
}
deinit {
print("person deinit")
}
}
let per = Person(name: "tom")
print(per.name)
}
//2、deinit的调用顺序
do{
/**
先调用子类的deinit
再调用父类的deinit
*/
print("---------2--------")
class Person {
var name:String
init(name:String){
self.name = name
}
deinit {
print("Person deinit")
}
}
class Student : Person {
var age:Int
init(age:Int,name:String){
self.age = age
super.init(name:name)
}
deinit {
print("Student deinit")
}
}
let stu = Student(age:18,name:"tom")
print(stu.name,stu.age)
}
}
行者常至,为者常成!