擴(kuò)展
Swift中的擴(kuò)展麸俘,對(duì)應(yīng)OC中的分類(lèi),可以用它來(lái)拓展類(lèi)的功能惧笛。
可以擴(kuò)展類(lèi)的什么:
添加新的屬性(只能是計(jì)算型屬性)从媚,且也不能為已有的屬性添加屬性觀察器;
添加新方法(實(shí)例方法和類(lèi)方法)患整;
添加新的構(gòu)造器(只是便利構(gòu)造器)拜效;
甚至還可以在該擴(kuò)展中使該類(lèi)符合某個(gè)協(xié)議,即申明該類(lèi)遵守某個(gè)協(xié)議各谚。
注意:
擴(kuò)展僅可以為類(lèi)添加新的功能紧憾,但不能重寫(xiě)該類(lèi)原有的方法等。
某類(lèi)的擴(kuò)展是可以訪問(wèn)該類(lèi)的屬性方法的昌渤。
擴(kuò)展語(yǔ)法:
extension Int
就表示這是對(duì)Int
類(lèi)型的擴(kuò)展赴穗。
extension Int {
var numStr: String {
get{
return "\(self)次"
}
}
func printTheNum() {
print(numStr)
}
func repeats(task: ()->Void) {
for _ in 0..<self {
task()
}
}
}
在Int
的擴(kuò)展中,我們首先為Int
添加了只讀計(jì)算型屬性numStr
,它是以該Int
型的數(shù)值拼接成的字符串般眉。然后又新添了兩個(gè)方法了赵。printTheNum()
方法的功能是打印numStr
屬性。repeats(task:)
方法有一個(gè)參數(shù)task
甸赃,其類(lèi)型為()->Void
柿汛,即沒(méi)有參數(shù)沒(méi)有返回值的閉包!傳入該方法的閉包將會(huì)被執(zhí)行該數(shù)值次埠对。
調(diào)用:
let num = 2
num.printTheNum() // log:2次
num.repeats {
print("i am your man")
}
// log: i am your man
// i am your man
可變實(shí)例方法:
如果在擴(kuò)展中新添的方法修改了self
或者self
的屬性络断,則必須以關(guān)鍵字mutating
標(biāo)注。
mutating func squre() {
self = self*self
}
泛型:
什么是泛型项玛?
通俗說(shuō)一下貌笨,就是一個(gè)函數(shù),或者類(lèi)稍计,使用到某個(gè)(或多個(gè))參數(shù)躁绸,這個(gè)參數(shù)的類(lèi)型,在設(shè)計(jì)期間是可供多選的臣嚣,那么這個(gè)函數(shù)(類(lèi))净刮,就稱(chēng)作泛型函數(shù)(泛型類(lèi))。
泛型約束:
泛型約束就是指定這個(gè)泛型使用到的可選類(lèi)型的選擇范圍——也就是說(shuō)指定它必須有的某些特征硅则,因?yàn)榉盒秃瘮?shù)(泛型類(lèi))里需要用到這些特征淹父,所以調(diào)用方使用泛型時(shí)候,指定的可選參數(shù)類(lèi)型也必須具有這些特征怎虫。
數(shù)字和字典這些集合類(lèi)就是典型的“泛型”暑认,這些集合可以存放很多類(lèi)型的數(shù)據(jù)。如果沒(méi)有泛型大审,那想象一下蘸际,我們得定義多少種數(shù)組初始化的方式。
協(xié)議:
協(xié)議是什么無(wú)需再做解釋?zhuān)苯觼?lái)看Swift中它的語(yǔ)法:
協(xié)議語(yǔ)法:
protocol SomProtocol {
// 這里是協(xié)議要定義的東西
}
在Swift中表示類(lèi)實(shí)現(xiàn)協(xié)議和繼承是一樣的徒扶,都用冒號(hào):
粮彤,若實(shí)現(xiàn)多個(gè)協(xié)議則多個(gè)協(xié)議之間同樣也用逗號(hào)隔開(kāi)。
當(dāng)一個(gè)類(lèi)既有繼承父類(lèi)姜骡,又實(shí)現(xiàn)了某協(xié)議時(shí)导坟。規(guī)定冒號(hào)后面先是繼承的類(lèi),然后才是實(shí)現(xiàn)的協(xié)議圈澈。
下面的代碼定義了一個(gè)StaffModel
類(lèi)惫周,它繼承于UserModel
,并且還實(shí)現(xiàn)了兩個(gè)協(xié)議SomProtocol
,OtherProtocol
康栈。
class StaffModel: UserModel, SomProtocol, OtherProtocol {
}
屬性要求:
協(xié)議中可以定義對(duì)所遵守該協(xié)議的類(lèi)中屬性的要求递递∨绯龋可以要求屬性的類(lèi)型、名字漾狼,以及可讀還是可寫(xiě)重慢。
下面定義的協(xié)議SomProtocol
中定義了所遵守該協(xié)議的類(lèi)中屬性的要求饥臂。必須要有個(gè)叫fullName
的逊躁,字符串類(lèi)型的,可讀可寫(xiě)的屬性隅熙。
protocol SomProtocol {
var fullName: String {get set}
}
方法要求:
協(xié)議中定義對(duì)方法的要求稽煤。只有方法的定義,沒(méi)有對(duì)應(yīng)的方法體囚戚。
protocol SomProtocol {
var fullName: String {get set}
func nameHandle(fullName: String) -> String
}
構(gòu)造器要求:
協(xié)議中也可以定義對(duì)構(gòu)造器的要求酵熙。基本和定義方法是一樣驰坊。但是在實(shí)現(xiàn)該協(xié)議的類(lèi)中實(shí)現(xiàn)該構(gòu)造器時(shí)匾二,無(wú)論在類(lèi)中是作為指定構(gòu)造器還是便利構(gòu)造器,都要在前面加上required
關(guān)鍵字拳芙。
protocol SomProtocol {
var fullName: String {get set}
init(fullName: String)
func nameHandle(fullName: String) -> String
}
class StaffModel: UserModel, SomProtocol {
var fullName: String = "" // SomProtocol協(xié)議要求的屬性
required init(fullName: String) { // 協(xié)議要求的構(gòu)造器
self.fullName = fullName
super.init()
}
func nameHandle(fullName: String) -> String { // 協(xié)議要求的方法
return "fullName:\(fullName)"
}
}
協(xié)議可以作為類(lèi)型
協(xié)議可以作為變/常量察藐、屬性、方法參數(shù)舟扎、集合類(lèi)元素的類(lèi)型分飞。表示實(shí)現(xiàn)了該協(xié)議的任何一種實(shí)例。
通過(guò)協(xié)議實(shí)現(xiàn)協(xié)議
有時(shí)不方便在原類(lèi)中實(shí)現(xiàn)協(xié)議睹限,那我們通過(guò)擴(kuò)展來(lái)實(shí)現(xiàn)協(xié)議可以達(dá)到一樣的效果譬猫。
更多請(qǐng)參考:Swift中協(xié)議的簡(jiǎn)單介紹