JHHK

欢迎来到我的个人网站
行者常至 为者常成

10_2、初始化器(二)

目录

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)
    }
}

行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.