美文网首页
Swift基础1——类

Swift基础1——类

作者: quantiza | 来源:发表于2018-11-23 10:03 被阅读0次

总览

类(Class)作为OOP的一个关键概念是必须要讨论的。类所包含的特性可以从OO的设计方法来阐述:封装,继承,多态和抽象。不同的语言对于类的描述有不同的方案,不过其OO的宗旨与原则是一致的。Swift语言提供了优秀的类支持,Swift 并不需要为类创建独立的接口和实现文件。你所要做的是 在一个单一文件中定义一个类或者结构体,系统将会自动生成面向其它代码的外部接口。Swift 的构造器无需返回值,它们的主要任务是保证新实例在第一次使用前完成正确的初始化。本文将从以下几个方面来review Swift中关于类的表述:

  • 类及其相关的数据结构
  • 属性和方法(延迟加载,计算属性,观察器,域)
  • 继承(重写方法和属性)
  • 构造过程(构造原理)
  • 析构过程(析构原理)

属性

构造过程

构造过程是指通过类构造一个对象的过程,这个过程中包括为对象分配内存空间以及初始化对象属性。OC中是通过向对象发送alloc和init消息实现这两步的(注意alloc发向类对象,init发向实例对象)。Swift中构造过程指的是初始化过程(Initialization),它分为两个步骤(two-phase):

  1. 为每个存储属性指定初始值。
  2. 在新实例准备使用之前进一步定制它们的存储型属性。

注意:Swift’s two-phase initialization process is similar to initialization in Objective-C. The main difference is that during phase 1, Objective-C assigns zero or null values (such as 0 or nil) to every property. Swift’s initialization flow is more flexible in that it lets you set custom initial values, and can cope with types for which 0 or nil is not a valid default value.[1]

这表明swift的two-phase构造方法比OC更加个性化,此外Swift编译器会执行4种检查以确保two-phase构造安全无误的完成:

  1. 确保指定构造器(Designed Initializer)中属性初始化完成再调用父类初始化构造器,这也正是上面所提及的Swift与OC构造过程的区别所在。
  2. 指定构造器先调用父类构造器再向继承的属性赋值。否则指定构造器赋值会被父类构造器覆盖
  3. 便利构造器(convenience initializer)必须先调用其他构造器,然后再为属性赋值。
  4. 构造器在第一阶段构造完成之前,不会生成有效实例,所以与实例相关的操作无效。

上面四条指定了构造器的编写规则,规则通过属性赋值与构造器调用的顺序保证了两件事:其一,确保生成有效实例(Designed);其二,构造器中属性赋值不被覆盖。

构造器类型

1. 默认构造器(default initializers)

2. 指定构造器(Designed Initializers)

  • 每个类至少有一个指定构造器,可以通过继承父类指定构造器满足这个条件
  • 初始化所有属性
  • 往上调用父类初始化方法

3. 便利构造器(Convenience Initializers)

  • 指定默认属性或创建一个特殊用途的实例
  • 需要调用指定初始化方法
  • 关键字convenience

4. 可失败构造器(Failable Initializers)

  • init?(或init!)形式的构造器
  • 通过return nil表达构造失败
  • 通过此构造器实例化的对象是optional类型
  • 子类可以重写该构造器(重写成正常构造器)

5. 必要构造器

  • 子类必须实现该构造器
  • 子类父类需用关键字required,子类里不用override关键字

6. 构造器调用规则

  • Rule1 指定构造器必须调用其父类的指定构造器。
  • Rule2 便利构造器必须调用同类中定义的其它构造器。
  • Rule3 便利构造器必须最终导致一个指定构造器被调用。
    这些调用规则与OC的构造器调用规则是一致的。一言以蔽之,所有构造器都要指向指定构造器(横向代理),指定构造器要指向父类指定构造器(向上代理),如下图所示[1]
image

继承

跟 Objective-C 中的子类不同,Swift 中的子类默认情况下不会继承父类的构造器。Swift 的这种机制可以防止 一个父类的简单构造器被一个更精细的子类继承,并被错误地用来创建子类的实例。通过override关键字重写父类方法。当满足特定条件时,父类构造器是可以被自动继承的。

  • Rule 1 没有指定构造器的类将继承父类的指定构造器
  • Rule 2 如果子类提供了所有父类指定构造器的实现(无论继承来的,还是自定义实现的),子类将自动继承父类所有的便利构造器。

Swift官方文档给出这样一个例子:

class Food {
    var name: String
    init(name: String) {
        self.name = name
    }
    convenience init() {
        self.init(name: "[Unnamed]")
} }

class RecipeIngredient: Food {
    var quantity: Int
    init(name: String, quantity: Int) {
        self.quantity = quantity
        super.init(name: name)
    }
    override convenience init(name: String) {
        self.init(name: name, quantity: 1)
} }

下图展示了它们的构造器链(initializer chain)


image
  1. https://docs.swift.org/swift-book/LanguageGuide/Initialization.html "Swift Initialization"

相关文章

  • Swift 基础(3) -- 根据类名创建对象

    1. 基础 Swift中的类名 在Swift中的类名是 : 命名空间 + 类名 .(比如:TestDemo.Per...

  • Swift基础1——类

    总览 类(Class)作为OOP的一个关键概念是必须要讨论的。类所包含的特性可以从OO的设计方法来阐述:封装,继承...

  • Programming in Swift 编程指南

    Swift 基础篇 Swift 语言基础 Swift 中的字符串和集合 Swift 中的类 Swift 中的结构体...

  • 接上面的基础语法(Swift中类的使用)

    类的介绍和定义 1.Swift 也是面向对象的语言,面向对象的基础是类,类产生的对象,那么Swift中如何定义类呢...

  • swift语言(swift3.0)基础知识(三)

    1、类的定义 1.1 Swift也是一门面向对象开发的语言。面向对象的基础是类,类产生了对象。 在Swift中如何...

  • 12 类

    1. 类的介绍和定义 Swift也是一门面向对象开发的语言 面向对象的基础是类,类产生了对象 在Swift中如何定...

  • Swift Optional ( 可选类型 ) 总结

    一、Optional 定义归纳 (1).Swift中声明一个变量或常量时需要返回nil。(2).Swift中基础类...

  • swift 基础方法的封装

    CTCateory swift oc 基本类用swift实现 前言 本文主要是针对swift封装基础方法类,方...

  • Swift中类的定义

    Swift中类的定义 Swift也是一门面向对象开发的语言 面向对象的基础是类,类产生了对象 在Swift中如何定...

  • Swift3.x - 类和结构体

    类的介绍和定义 Swift也是一门面向对象的开发语言。 面向对象的基础就是类,类产生对象。 Swift如何定义类:...

网友评论

      本文标题:Swift基础1——类

      本文链接:https://www.haomeiwen.com/subject/hmpqqqtx.html