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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mangosnow/article/details/54379080

类继承方法重载

可使用 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方法

猜你喜欢

转载自blog.csdn.net/mangosnow/article/details/54379080
今日推荐