本文源自本人的學(xué)習(xí)記錄整理與理解桥温,其中參考閱讀了部分優(yōu)秀的博客和書(shū)籍引矩,盡量以通俗簡(jiǎn)單的語(yǔ)句轉(zhuǎn)述。引用到的地方如有遺漏或未能一一列舉原文出處還望見(jiàn)諒與指出侵浸,另文章內(nèi)容如有不妥之處還望指教旺韭,萬(wàn)分感謝。
方法
- 枚舉掏觉、結(jié)構(gòu)體区端、類(lèi)都可以定義實(shí)例方法、類(lèi)方法
- 實(shí)例方法:通過(guò)實(shí)例對(duì)象調(diào)用
- 類(lèi)方法:通過(guò)類(lèi)型調(diào)用澳腹,用
static
或者class
關(guān)鍵字定義 -
self
: 在實(shí)例方法中代表實(shí)例對(duì)象织盼,在類(lèi)型方法中代表類(lèi)型
class Person {
static var cout = 0
init() {
Person.cout += 1
}
//這里的cout 等價(jià)于self.cout、Person.self.cout酱塔、Person.cout
static func getCount() -> Int {
cout
}
}
mutating
- 結(jié)構(gòu)體和枚舉是值類(lèi)型沥邻,
默認(rèn)情況
下值類(lèi)型屬性不能被自身的實(shí)例方法修改 - 可以考慮在
func
關(guān)鍵字前加mutating
可以允許這種修改行
struct Person {
var x = 0.0, y = 0.0
mutating func run(deltX:Double, deltY:Double) {
x += deltX
y += deltY
}
@discardableResult
- 在func前面加@discardableResult,可以消除:函數(shù)調(diào)用后返回值未被使用的警告??
struct Point {
var x = 0.0, y = 0.0
@discardableResult mutating func moveX(deltaX: Double) -> Double {
x += deltaX
return x
}
}
var p = Point()
p. moveX(deltaX:10)
下標(biāo)
- 使用
subscript
可以給任意類(lèi)型(枚舉延旧、結(jié)構(gòu)體谋国、類(lèi))增加下標(biāo)功能槽地,有些地方也翻譯為:下標(biāo)腳本
迁沫;subscript
的語(yǔ)法類(lèi)似于實(shí)例方法、計(jì)算屬性捌蚊,本質(zhì)就是方法(函數(shù)) -
subscript
中定義的返回值類(lèi)型決定了:
-
get
方法的返回值類(lèi)型 -
set
方法中newValue
的類(lèi)型 -
subscript
可以接受多個(gè)參數(shù)集畅,并且類(lèi)型任意 -
subscript
可以沒(méi)有set
方法,但必須要有get
方法缅糟;如果只有get
方法時(shí)可以省略get
class Point {
var x = 0.0, y = 0.0
//index:標(biāo)簽
subscript(index: Int) -> Double {
set {
if index ==0 {
x = newValue
}else if index == 1 {
y = newValue
}
}
get {
if index == 0 {
return x
}else if index == 1 {
return y
}
}
}
}
var p = Point()
p[0] = 11.3
p[1] = 22.2
print(p.x)//11.3
print(p.y)//22.2
print(p[0])//11.3
print(p[1])//22.2
注意點(diǎn):如果下標(biāo)的返回值是枚舉挺智,就不能拿到返回的枚舉直接修改其成員,需要再subscript內(nèi)部實(shí)現(xiàn)set方法窗宦;如果下標(biāo)返回值是類(lèi)赦颇,就不需要如此
- 接收多個(gè)參數(shù)的下標(biāo)
實(shí)例.png
繼承
值類(lèi)型(枚舉二鳄、結(jié)構(gòu)體)不支持集成,只有類(lèi)支持繼承
沒(méi)有父類(lèi)的類(lèi)稱(chēng)之為:基類(lèi)媒怯,就是說(shuō)隨便自定義一個(gè)類(lèi)订讼,只要沒(méi)繼承其他類(lèi),那這個(gè)類(lèi)就是基類(lèi)
Swift
并沒(méi)有像OC
扇苞、Java
那樣的規(guī)定:任何類(lèi)最終都要繼承自某個(gè)基類(lèi)子類(lèi)可以重寫(xiě)父類(lèi)的
下標(biāo)
欺殿、方法
、屬性
鳖敷,重寫(xiě)必須加上override
關(guān)鍵字屬性繼承的內(nèi)存示例
示例.png
- 重寫(xiě)實(shí)例方法脖苏、下標(biāo)必須加
override
示例.png
- 重寫(xiě)類(lèi)型方法、下標(biāo)
- 被
class
修飾的類(lèi)型方法定踱、下標(biāo)棍潘,允許
被子類(lèi)重寫(xiě) - 被
static
修飾的類(lèi)型方法、下標(biāo)崖媚,不允許
被子類(lèi)重寫(xiě) - 如果父類(lèi)定義方法時(shí)使用class修飾蜒谤,子類(lèi)重寫(xiě)時(shí)可以使用class也可以使用static來(lái)修飾
class示例.png
static示例.png
- 重寫(xiě)
實(shí)例
屬性
- 子類(lèi)
可以
將父類(lèi)的屬性(存儲(chǔ)、計(jì)算)至扰,重寫(xiě)為計(jì)算屬性
- 相反子類(lèi)
不可以
將父類(lèi)的屬性(存儲(chǔ)鳍徽、計(jì)算),重寫(xiě)為存儲(chǔ)屬性
- 只能重寫(xiě)var屬性敢课,不能重寫(xiě)let屬性
- 重寫(xiě)時(shí)屬性名阶祭、類(lèi)型要一致
- 子類(lèi)重寫(xiě)后的屬性權(quán)限不能小于父類(lèi)的權(quán)限
5.1> 如果父類(lèi)屬性是只讀的,那么子類(lèi)重寫(xiě)后的屬性可以是只讀的直秆、也可以是可讀可寫(xiě)的
5.2> 如果父類(lèi)屬性是可讀可寫(xiě)的濒募,那么子類(lèi)重寫(xiě)后的屬性也必須是可讀可寫(xiě)的
基類(lèi)Circle.png
重寫(xiě)屬性.png
- 重寫(xiě)
類(lèi)型
屬性
- 被
class
修飾的計(jì)算類(lèi)型屬性,可以被子類(lèi)重寫(xiě) - 被
static
修飾的類(lèi)型屬性(存儲(chǔ)圾结、計(jì)算)瑰剃,不可以被子類(lèi)重寫(xiě)
示例.png
- 屬性觀(guān)察器
- 可以在子類(lèi)中為父類(lèi)屬性(除了只讀計(jì)算屬性、
let
屬性)增加屬性觀(guān)察器:willSet
筝野、didSet
class Circle {
//存儲(chǔ)屬性
var redius: Int = 1
}
class SubCircle: Circle {
override var redius: Int {
willSet {
print("SubCircle willSetRedius",newValue)
}
didSet {
print("SubCircle didSet Redius",newValue)
}
}
}
var circle = SubCircle()
circle.radius = 10
示例2.png
-final
- 被
final
修飾的方法晌姚、下標(biāo)、屬性歇竟,禁止被重寫(xiě) - 被
final
修飾的類(lèi)挥唠,禁止被繼承
多態(tài)的實(shí)現(xiàn)原理
- OC : 通過(guò)Runtime的API來(lái)實(shí)現(xiàn)
- C++ : 虛表(虛函數(shù)表)
- Swift : 類(lèi)似于C++的實(shí)現(xiàn)方式,也是通過(guò)一張表