zoukankan      html  css  js  c++  java
  • 构造器(二)----指定构造器、便利构造器

    在上一篇博客中简介了构造器基础层面的知识构造器(一),以下我们深入的学习类的构造器应用。

    在Swift中类一共同拥有两种构造器:

    • 指定构造器
    • 便利构造器

    什么是指定构造器,有什么作用?

    我个人的理解为在类中没有加不论什么keyword的构造器称为指定构造器。作用为初始化类中全部的实例存储属性

    init()
    {
       ...
    }
    

    什么是便利构造器,有什么作用?

    我个人理解为在类中(仅仅能在类中,结构体和枚举里面是没有的)加上conveniencekeyword的构造器为便利构造器,作用为辅助性调用指定构造器进行一系列的工作。感觉体现了在Object-C中的代理模式

     convenience init()
     {
         ...
     //注意这里必须调用同一类的其它构造器,这里调用的能够是其它便利构造器或者是指定构造器
     }
    

    综合的看一个励志吧,请原谅程序猿的屌丝:

             class Man
        {
        var say:String
         init(say:String)
        {
        self.say=say
        }
    
        convenience init(Say:String)
        {
            self.init(say:Say)
    
        }
    }
        var man1=Man(say: "我喜欢你!

    ") print(man1.say) var man2=Man(Say: "啊,不,我不喜欢你!我爱你!

    ") print(man2.say)

    构造器的调用链遵守三条规则

    • 子类构造器必须调用直接父类的指定构造器
    • 便利构造器必须调用同一类中的其它构造器
    • 便利构造器调用的构造器的终点必须是指定构造器

    类构造的两个阶段:

    第一阶段:

    1. 程序调用子类的某个构造器

    2. 为实例分配内存, 此时实例的内存还没有被初始化

    3. 指定构造器确保子类定义的全部实例存储属性都已被赋初值

    4. 指定构造器将调用父类的构造器, 完毕父类定义的实例存储属性的初始化

    5. 沿着调用父类构造器的构造器链一直往上运行, 直到到达构造器链的最顶部

    第二阶段:

    1. 沿着继承树往下, 构造器此时能够改动实例属性和訪问self, 甚至能够调用实例方法

    2. 最后, 构造器链中的便利构造器都有机会定制实例和使用self

    Swift安全检查

    • 安全检查1:指定构造器必须先初始化当前类中定义的实例存储属性, 然后才干向上调用父类构造器

    • 安全检查2:指定构造器必须向上调用父类构造器, 然后才干对继承得到的属性赋值

    • 安全检查3:便利构造器必须先调用同一个类的其它构造器, 然后才干对属性赋值

    • 安全检查4:构造器在第一阶段完毕之前, 不能调用实例方法, 不能读取实例属性

      class Person {
      
      var name: String!
      var weight: Double
      
      // 定义指定构造器
      init(name: String, weight: Double) {
          self.name = name
          self.weight = weight
      }
      
      // 定义便利构造器(使用convenience修饰)
      convenience init(n name: String, w weight: Double) {
          self.init(name: name, weight: weight)
      }
      

      }

      class Man: Person {
      
      var sex: String!
      
      init(sex: String, name: String, weight: Double) {
      // print(super.name) 不能再父类初始化之前调用父类中的属性
      super.init(name: name, weight: weight)
      super.name = "lala"
      print(self.name)
      // print(self.sex) 不能在本类中的属性没有进行初始化的时候进行调用
      // 会出现:fatal error: unexpectedly found nil while unwrapping an Optional value错误
      self.sex = sex
      print(self.sex)
      }
      
      convenience init(s sex: String, n name: String, weight: Double) {
      
      // 在调用其它构造器之前, 不能訪问或改动不论什么实例存储属性
      // print(self.name) 错误
      // super.name = name 错误
      self.init(sex: sex, name: name, weight: weight)
      }
      }
      var man = Man(sex: "男", name: "Rinpe", weight: 62.0)
      
  • 相关阅读:
    Word pair Hu
    [bzoj1601] 灌水
    小木棍
    雇佣计划
    [Luogu1282] 多米诺骨牌
    [Luogu1216] 数字三角形
    [Luogu1734] 最大约数和
    [NOIp2008] 传纸条
    [Luogu1325] 雷达安装
    nginx
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/7127800.html
Copyright © 2011-2022 走看看