網站首頁 編程語言 正文
初始化
初始化器
1、類、結構體、枚舉都可以定義初始化器
class Size {
init(age: Int) {
}
}
var s = Size(age: 10)
2、類有2種初始化器:指定初始化器(deaignated initializer)、便捷初始化器(convenience initializer)
class Size {
//指定初始化器
init(age: Int) {
}
//便捷初始化器
convenience init(age: Int) {
}
}
3、每個類至少有一個指定初始化器,指定初始化器是類的主要初始化器
4、默認初始化器總是類的指定初始化器
5、類偏向于少量指定初始化器,一個類通常只有一個指定初始化器
6、初始化器的相互調用規則,會更安全
指定初始化器必須從它的直系父類調用指定初始化器;
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(age: age)
}
}
便捷初始化器必須從相同的類里調用另一個初始化器;
便捷初始化器最終必須調用一個指定初始化器;
class Size {
var width: Int
var height: Int
init(width: Int, height: Int) {
self.width = width
self.height = height
}
convenience init(width: Int) {
self.init(width: width, height: 0)
}
convenience init(height: Int) {
self.init(width: 0, height: height)
}
convenience init() {
self.init(width: 0, height: 0)
}
}
var s1 = Size(width: 10, height: 20)
var s2 = Size(width: 10)
var s3 = Size(height: 20)
var s4 = Size()
初始化器的相互調用
兩段式初始化
1、Swift在編碼安全方面是煞費苦心,為了保證初始化過程的安全,設定了兩段式初始化、安全檢查。
2、兩段式初始化,第1階段:初始化所有存儲屬性
- 外層調用指定\便捷初始化器
- 分配內存給實例,但未初始化
- 指定初始化器確保當前類定義的存儲屬性都初始化
- 指定初始化器調用父類的初始化器,不斷向上調用,形成初始化器鏈
3、兩段式初始化,第2階段:設置新的存儲屬性值
從頂部初始化器往下,鏈中的每一個指定初始化器都有機會進一步定制實例
初始化器現在能夠使用self(訪問、修改它的屬性,調用它的實例方法等等)
最終,鏈中任何便捷初始化器都有機會定制實例以及使用self
class Person {
var age: Int
init(age: Int) {
self.age = age
self.test()
}
func test() {
}
}
class Student: Person {
var score: Int
init(age: Int, score: Int) {
self.score = score
super.init(age: age)
}
convenience init() {
self.init(age: 0, score: 0)
}
}
安全檢查
1、指定初始化器必須保證在調用父類初始化器之前,其所在類定義的所有存儲屬性都要初始化完成
2、指定初始化器必須先調用父類初始化器,然后才能為繼承的屬性設置新值
3、便捷初始化器必須先調用同類中的其他初始化器,然后再為任意屬性設置新值
4、初始化器在第1階段初始化完成之前,不能調用任何實例方法,不能讀取任何實例屬性的值,也不能引用self
重寫
1、當重寫父類的指定初始化器時,必須加上override(即使子類的實現是便捷初始化器)
2、如果子類寫了一個匹配父類便捷初始化器的初始化器,不用加上override
因為父類的便捷初始化器永遠不會通過子類直接調用,因此,嚴格來說,子類無法無法重寫
父類的便捷初始化器。
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(age: age)
}
init() {
self.score = 0
super.init(age: 0)
}
}
自動繼承
1、如果子類沒有自定義任何指定初始化器,他會自動繼承父類所有的指定初始化器
2、如果子類提供了父類所有指定初始化器的實現(要么通過方式1繼承,要么重寫)
子類會自動繼承所有的父類便捷初始化器
3、就算子類添加了更多的便捷初始化器,這些規則仍然適用
class Person {
var age: Int
var name: String
init(age: Int, name: String) {
self.age = age
self.name = name
}
init() {
self.age = 0
self.name = ""
}
convenience init(age: Int) {
self.init(age: age, name: "")
}
convenience init(name: String) {
self.init(age: 0, name: name)
}
}
class Student: Person {
var no: Int = 0
convenience init(no: Int) {
self.init()
}
}
原文鏈接:https://blog.csdn.net/run_in_road/article/details/125654292
相關推薦
- 2022-07-24 .Net行為型設計模式之中介者模式(Mediator)_基礎應用
- 2022-10-01 Iptables防火墻limit模塊擴展匹配規則詳解_安全相關
- 2022-11-03 python中for循環的多種使用實例_python
- 2022-01-03 踩坑解決mongoose對已經存在的集合查詢,查詢條件不起限制作用的問題
- 2022-05-04 詳解python的異常捕獲_python
- 2022-04-10 SQL?server中提示對象名無效的解決方法_MsSql
- 2024-01-28 spring自動配置的原理
- 2022-05-26 Python?pass語句作用和Python?assert斷言函數的用法_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支