初始化器

This commit is contained in:
2022-01-13 10:53:35 +08:00
parent 2cbad07435
commit 30fc64948d
7 changed files with 296 additions and 1 deletions

View File

@@ -222,4 +222,9 @@ circle.radius = 10
`final` 修饰的方法、下标、属性,禁止被重写
`final` 修饰的类,禁止被继承
`final` 修饰的类,禁止被继承
#### 多态
父类引用指向子类对象

View File

@@ -0,0 +1,104 @@
import UIKit
// init()
//class Size {
// var width: Int = 0
// var height: Int = 0
//}
//
//class Size {
// var width: Int
// var height: Int
//
// init() {
// width = 0
// height = 0
// }
//}
class Size {
var width: Int = 0
var height: Int = 0
//
// init()
init(width: Int, height: Int) {
self.width = width
self.height = height
}
// 便
convenience init(width: Int) {
self.init(width: width, height: 0)
}
}
var s1 = Size(width: 10, height: 20)
var s2 = Size(width: 30)
class Person {
var age: Int
//
init(age: Int) {
self.age = age
}
// 便
convenience init() {
self.init(age: 0)
}
}
class Student: Person {
var score: Int
//
init(age: Int, score: Int) {
self.score = score
// super.init
super.init(age: age)
}
// 便便
convenience init() {
self.init(score: 0)
}
// 便
convenience init(score: Int) {
self.init(age: 0, score: score)
}
}
class Animal {
var legs: Int
var name: String
var age: Int
init(name: String, age: Int, legs: Int) {
self.legs = legs
self.age = age
self.name = name
}
init(name: String, age: Int) {
self.legs = 4
self.age = age
self.name = name
}
convenience init(name: String) {
self.init(name: name, age: 1, legs: 4)
}
}
class Cat: Animal {
}
var cat = Cat(name: "淘气", age: 3, legs: 4)
var cat1 = Cat(name: "淘气", age: 3)
var cat2 = Cat(name: "淘气")

View File

@@ -0,0 +1,175 @@
---
gitea: none
include_toc: true
---
### 初始化器
类、结构体、枚举都可以定义初始化器。类的两种初始化器如下所示
* 指定初始化器designated initializer
* 便捷初始化器convenience initializer: 便捷初始化器的前边有 `convenience` 关键字,只能进行当前类横向调用。
```swift
// 类的属性有初始值的时候,默认会有一个 init() 的初始化器
class Size {
var width: Int = 0
var height: Int = 0
}
// 等价于
class Size {
var width: Int
var height: Int
// 指定初始化器
init() {
width = 0
height = 0
}
}
class Size {
var width: Int = 0
var height: Int = 0
// 指定初始化器(主要初始化器)
// 用户指定完初始化器之后,会覆盖掉原来的 init()初始化器
init(width: Int, height: Int) {
self.width = width
self.height = height
}
// 便捷初始化器
convenience init(width: Int) {
self.init(width: width, height: 0)
}
}
var s1 = Size(width: 10, height: 20)
var s2 = Size(width: 30)
```
#### 类初始化器
1. 每个类至少有一个指定初始化器,指定初始化器是类的主要初始化器
2. 默认初始化器总是类的指定初始化器
3. 类偏向于少量指定初始化器,一个类通常只有一个指定初始化器
#### 初始化器的相互调用
1. 指定初始化器必须从它的直系父类调用指定初始化器
2. 便捷初始化器必须从相同的类里调用另一个初始化器
3. 便捷初始化器最终必须调用一个指定初始化器
```swift
class Person {
var age: Int
// 指定初始化器
init(age: Int) {
self.age = age
}
// 便捷初始化器
convenience init() {
self.init(age: 0)
}
}
class Student: Person {
var score: Int
// 指定初始化器调用直系父类的初始化器
init(age: Int, score: Int) {
self.score = score
// super.init 方法放到最后
super.init(age: age)
// 个性化定制代码
...
}
// 便捷初始化器调用便捷初始化器
convenience init() {
self.init(score: 0)
}
// 便捷初始化器调用指定初始化器
convenience init(score: Int) {
self.init(age: 0, score: score)
}
}
```
初始化器的调用规则如下图所示
<img src="/Users/jiulinxiri/Library/Application%20Support/typora-user-images/image-20220113091257659.png" alt="image-20220113091257659" style="zoom:50%;" />
#### 两段式初始化
第1阶段初始化所有存储属性
* 外层调用指定\便捷初始化器
* 分配内存给实例,但未初始化
* 指定初始化器确保当前类定义的存储属性都初始化
* 指定初始化器调用父类的初始化器,不断向上调用,形成初始化器链
第2阶段设置新的存储属性值
* 从顶部初始化器往下,链中的每一个指定初始化器都有机会进一步定制实例
* 初始化器现在能够使用self访问、修改它的属性调用它的实例方法等等
* 最终链中任何便捷初始化器都有机会定制实例以及使用self
#### 重写
初始化器的重写,即子类重写父类的初始化器方法。
* 当重写父类的指定初始化器时,必须加上 `override`(即使子类的实现是便捷初始化器)
* 如果子类写了一个匹配父类便捷初始化器的初始化器,不用加上 `override`
* 因为父类的便捷初始化器永远不会通过子类直接调用
#### 自动继承
①如果子类没有自定义任何指定初始化器,它会自动继承父类所有的指定初始化器。
```swift
class Animal {
var legs: Int
var name: String
var age: Int
init(name: String, age: Int, legs: Int) {
self.legs = legs
self.age = age
self.name = name
}
init(name: String, age: Int) {
self.legs = 4
self.age = age
self.name = name
}
convenience init(name: String) {
self.init(name: name, age: 1, legs: 4)
}
}
class Cat: Animal {
}
// Cat 继承父类所有的指定初始化器
var cat = Cat(name: "淘气", age: 3, legs: 4)
var cat1 = Cat(name: "淘气", age: 3)
// 子类自动继承所有的父类便捷初始化器
var cat2 = Cat(name: "淘气")
```
②如果子类提供了父类所有指定初始化器的实现(要么通过方式①继承,要么重写)
* 子类自动继承所有的父类便捷初始化器
③就算子类添加了更多的便捷初始化器,这些规则仍然适用
④子类以便捷初始化器的形式重写父类的指定初始化器,也可以作为满足规则②的一部分

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='ios' buildActiveScheme='true' importAppTypes='true'>
<timeline fileName='timeline.xctimeline'/>
</playground>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:">
</FileRef>
</Workspace>