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)
      
  • 相关阅读:
    UVa 10118 记忆化搜索 Free Candies
    CodeForces 568B DP Symmetric and Transitive
    UVa 11695 树的直径 Flight Planning
    UVa 10934 DP Dropping water balloons
    CodeForces 543D 树形DP Road Improvement
    CodeForces 570E DP Pig and Palindromes
    HDU 5396 区间DP 数学 Expression
    HDU 5402 模拟 构造 Travelling Salesman Problem
    HDU 5399 数学 Too Simple
    CodeForces 567F DP Mausoleum
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/7127800.html
Copyright © 2011-2022 走看看