加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Swift 学习笔记 [3] 类 重载和构造器

发布时间:2020-12-14 06:28:59 所属栏目:百科 来源:网络整理
导读:类继承方法重载 可使用 override 修饰 被重写的方法 父类的属性(存储、计算属性均可override) 属性观察者 父类的下标 final 关键字 用final 防止重写,final关键字可以修饰类、属性、方法和下标。 final 不可以修饰方法中的局部变量,也不能修饰全局变量。

类继承方法重载

可使用 override 修饰

  1. 被重写的方法
  2. 父类的属性(存储、计算属性均可override)
  3. 属性观察者
  4. 父类的下标

final 关键字

  1. 用final 防止重写,final关键字可以修饰类、属性、方法和下标。
  2. final 不可以修饰方法中的局部变量,也不能修饰全局变量。
  3. 在类中使用 static修饰类的方法、属性,表示不可被重写,相当于 class + final 的效果

构造器

类的两种构造器

init(形参){}
  1. 指定构造器定义: 一个或者多个初始化所有实例属性,可调用父类的构造器,然后初始化本类的存储属性
  2. 便利构造器定义: 次要的、辅助行的构造器,通过调用同一个类的其他构造器(可以是指定、也可是便利,但最原始的一定指定构造器)完成初始化, 用convenience 修饰。

构造器链

  1. 指定构造器必须调用直接父类的指定构造器
  2. 便利构造器必须调用同一个类的其他构造器
  3. 便利构造器调用的构造器最终节点必须是指定构造器: 便利构造器-… - 指定构造器 (…表示本类的任何构造器)

两段式构造

Swift类的构造要两个阶段完成

第一阶段: 为存储属性分配内容,使用本类构造器初始化由本类定义的存储属性

  1. 调用子类构造器
  2. 分配内存
  3. 指定构造器确保子类定义的所有实例存储均已赋值
  4. 指定构造器调用父类的构造器,完成父类定义的实例存储属性
  5. 沿着继承树往上重复4步骤。

第二阶段: 从最顶层父类开始,沿着顶部构造器链往下,每个构造器都可再次修改存储属性。

  1. 沿着继承树下,构造器链中指定构造器有机会进一步定制实例,修改实例属性、访问self、调用实例方法
  2. 重复1步骤,所有的便利构造器都有机会定制实例,使用self。

这个流程解决的问题

  1. 过程安全
  2. 每一个类层次都获得完全的控制权
  3. 防止属性初始化之前被访问
  4. 防止属性被另一个构造器意外赋予不同的值

Swift内部检查

  1. 指定构造器必须先初始化自己类的实例存储属性,才能向上调用父类构造器
  2. 指定构造器必须向上调用父类构造器,才能得到继承下来的属性,然后才能赋值。 顺序不对会导致刚赋值但是被构造器覆盖掉了。
  3. 便利构造器先调用同类的其他(指定)构造器,才能对属性赋值。 和2检查原因一样,担心赋值被覆盖
  4. 构造器在第一阶段完成前,不能调用实例方法,不能读取实例属性。 (实际上是对第二阶段的进一步解释)

我对构造器的理解:

1. 指定构造器:最原始可以完成初始化的方法
2. 便利构造器:在指定构造器基础上方便定制化的一些方法,最终还是依赖指定构造器。
这样可以方便理解构造器链。

构造阶段,基本原则

1. 准确性(赋值了就一定得到赋值的操作结果,无二义性)
2. 顺应类继承关系。
3. 如果一个对象没有初始化,对它属性操作就是非法的。
结合第一阶段和第二阶段构造,再参考内部检查就容易理解了

构造器的继承和重写

  1. 如果没提供任何指定构造器,则自动继承父类所有指定构造器
  2. 如果子类实现了父类所有的指定构造器,无论是规则1继承的,还是自己写的,都将自动继承父类所有的便利构造器

四种情况

子类指定 <- 父类指定 Y
子类指定 <- 父类便利 N 子类是不会调用父类的便利构造器的
子类便利 <- 父类指定 Y
子类便利 <- 父类便利 N 子类是不会调用父类便利构造器的

结论:

  1. 父类便利构造器是不能重载的,因为违背了子类智能调用父类指定构造器的。
  2. 父类指定构造器可以被重载为子类便利构造器和子类指定构造器。

可能失败的构造器

可能失败的构造器的传播
普通构造器不能调用同一个类型的可能失败的构造器

子类必须包含的构造器

定义:申明所有子类必须包含该require构造器(指定和便利均可),表示为 require init() {}

析构器

deinit 方法,没有返回值,没有参数,所以不能重载 deinit { } swift 会自己调用父类的deinit方法

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读