14-協(xié)議

\color{green}{協(xié)議(Protocol)}

  • 協(xié)議可以用來定義方法、屬性夹纫、下標(biāo)的聲明咽瓷,協(xié)議可以被枚舉、結(jié)構(gòu)體捷凄、類遵守(多個(gè)協(xié)議之間用逗號(hào)隔開)
protocol Drawable {
  func draw()
     var x: Int { get set }
     var y: Int { get }
     subscript(index: Int) -> Int { get set }                                             
} 
protocol Test1 {}
protocol Test2 {}
protocol Test3 {}
class TestClass : Test1, Test2, Test3 {}
  • 協(xié)議中定義方法時(shí)不能有默認(rèn)參數(shù)值

  • 默認(rèn)情況下忱详,協(xié)議中定義的內(nèi)容必須全部都實(shí)現(xiàn)

  • 也有辦法辦到只實(shí)現(xiàn)部分內(nèi)容,以后的課程會(huì)講到

\color{green}{協(xié)議中的屬性}

protocol Drawable {
    func draw()                                           
    var x: Int { get set }
    var y: Int { get }
    subscript(index: Int) -> Int { get set }                                               
} 
class Person : Drawable {
    var x: Int = 0
    let y: Int = 0
    func draw() {
        print("Person draw")
    }                                            
    subscript(index: Int) -> Int { 
        set {}                                              
        get { index } 
    }                                              
}
class Person : Drawable {
    var x: Int {                                       
        get { 0 }                                          
        set {} 
    }                                              
    var y: Int { 0 }
    func draw() { print("Person draw") } 
    subscript(index: Int) -> Int { 
        set {}
        get { index }
    }
}
  • 協(xié)議中定義屬性時(shí)必須用 \color{green}{var}關(guān)鍵字
  • 實(shí)現(xiàn)協(xié)議時(shí)的屬性權(quán)限要\color{blue}{不小于}協(xié)議中定義的屬性權(quán)限
  • 協(xié)議定義\color{green}{get}跺涤、\color{green}{set}匈睁,用\color{green}{var}存儲(chǔ)屬性或\color{green}{get}\color{green}{set}計(jì)算屬性去實(shí)現(xiàn)
  • 協(xié)議定義\color{green}{get}桶错,用任何屬性都可以實(shí)現(xiàn)

\color{green}{static} \color{green}{class}

  • 為了保證通用航唆,協(xié)議中必須用\color{green}{static}定義類型方法、類型屬性院刁、類型下標(biāo)
protocol Drawable {
  static func draw()                                      
} 

class Person1 : Drawable {
  class func draw() {
     print("Person1 draw")
  }                                             
} 

class Person2 : Drawable {
   static func draw() {
     print("Person2 draw")
   }                                              
} 

\color{green}{mutating}

  • 只有將協(xié)議中的實(shí)例方法標(biāo)記為mutating
  • 才允許結(jié)構(gòu)體糯钙、枚舉的具體實(shí)現(xiàn)修改自身內(nèi)存
  • 類在實(shí)現(xiàn)方法時(shí)不用加mutating,枚舉、結(jié)構(gòu)體才需要加mutating
protocol Drawable {
     mutating func draw()
} 

class Size : Drawable {
     var width: Int = 0
     func draw() {                                        
        width = 10 
     }                                             
} 

struct Point : Drawable {
     var x: Int = 0
     mutating func draw() {
         x = 10 
     } 
} 

\color{green}{init}

  • 協(xié)議中還可以定義初始化器init
  • 非final類實(shí)現(xiàn)時(shí)必須加上\color{green}{required}
protocol Drawable {
   init(x: Int, y: Int)    
} 

class Point : Drawable { 
   required init(x: Int, y: Int) {} }} 
}

final class Size : Drawable {
    init(x: Int, y: Int) {}                                              
} 

  • 如果從協(xié)議實(shí)現(xiàn)的初始化器任岸,剛好是重寫了父類的指定初始化器

  • 那么這個(gè)初始化必須同時(shí)加\color{green}{required}再榄、\color{green}{override}

protocol Livable {
   init(age: Int)                                              
}  

class Person {                                         
    init(age: Int) {}
} 

class Student : Person, Livable {
    required override init(age: Int) {
       super.init(age: age)            
    }
}

\color{green}{init} \color{green}{init?} \color{green}{init!}

  • 協(xié)議中定義的init?享潜、init!困鸥,可以用init、init?剑按、init!去實(shí)現(xiàn)
  • 協(xié)議中定義的init疾就,可以用init、init!去實(shí)現(xiàn)
protocol Livable {
    init()
    init?(age: Int)
    init!(no: Int)
}

class Person : Livable {
    required init() {}
    // required init!() {}                                      

    required init?(age: Int) {}
    // required init!(age: Int) {}
    // required init(age: Int) {}

    required init!(no: Int) {}
    // required init?(no: Int) {}
    // required init(no: Int) {}                       
} 

\color{green}{協(xié)議的繼承}

  • 一個(gè)協(xié)議可以繼承其他協(xié)議
protocol Runnable {
   func run()                                                 
} 

protocol Livable : Runnable {
   func breath()                                             
} 

class Person : Livable {
   func breath() {}
   func run() {}                                             
} 

\color{green}{協(xié)議組合}

  • 協(xié)議組合艺蝴,可以包含1個(gè)類類型(最多1個(gè))
protocol Livable {}
protocol Runnable {}
class Person {}
// 接收Person或者其子類的實(shí)例
 func fn0(obj: Person) {}
 // 接收遵守Livable協(xié)議的實(shí)例
 func fn1(obj: Livable) {}
 // 接收同時(shí)遵守Livable猬腰、Runnable協(xié)議的實(shí)例
 func fn2(obj: Livable & Runnable) {}
 // 接收同時(shí)遵守Livable、Runnable協(xié)議猜敢、并且是Person或者其子類的實(shí)例 
 func fn3(obj: Person & Livable & Runnable) {} 
typealias RealPerson = Person & Livable & Runnable
 // 接收同時(shí)遵守Livable姑荷、Runnable協(xié)議、并且是Person或者其子類的實(shí)例 
func fn4(obj: RealPerson) {} 

\color{green}{CaseIterable}

  • 讓枚舉遵守\color{green}{CaseIterable}協(xié)議缩擂,可以實(shí)現(xiàn)遍歷枚舉值
enum Season : CaseIterable {
    case spring, summer, autumn, winter
}

let seasons = Season.allCases
print(seasons.count) // 4
for season in seasons {
    print(season)
} // spring summer autumn winter

\color{green}{CustomStringConvertible}

  • 遵守CustomStringConvertible厢拭、 CustomDebugStringConvertible協(xié)議,都可以自定義實(shí)例的打印字符串
class Person : CustomStringConvertible, CustomDebugStringConvertible { 
    var age = 0                                                  
    var description: String { "person_\(age)" }                                              
    var debugDescription: String { "debug_person_\(age)" } 
}                                              
var person = Person()
print(person) // person_0 
debugPrint(person) // debug_person_0 
  • print調(diào)用的是CustomStringConvertible協(xié)議的description

  • debugPrint撇叁、po調(diào)用的是CustomDebugStringConvertible協(xié)議的debugDescription

image.png

\color{green}{Any} \color{green}{AnyObject}

  • Swift提供了2種特殊的類型:\color{green}{Any} \color{green}{AnyObject}
    \color{green}{*} Any:可以代表任意類型(枚舉供鸠、結(jié)構(gòu)體、類陨闹,也包括函數(shù)類型)
    \color{green}{*} AnyObject:可以代表任意類類型(在協(xié)議后面寫上: \color{green}{AnyObject}代表只有類能遵守這個(gè)協(xié)議)
    \color{green}{??} 在協(xié)議后面寫上: \color{green}{class}也代表只有類能遵守這個(gè)協(xié)議
var stu: Any = 10
stu = "Jack"
stu = Student()
// 創(chuàng)建1個(gè)能存放任意類型的數(shù)組 
// var data = Array<Any>() 
var data = [Any]() 
data.append(1) 
data.append(3.14) 
data.append(Student()) 
data.append("Jack") 
data.append({ 10 }) 

\color{green}{is} \color{green}{as?} \color{green}{as!} \color{green}{as}

  • is用來判斷是否為某種類型楞捂,as用來做強(qiáng)制類型轉(zhuǎn)換
protocol Runnable { func run() } 
class Person {}
class Student : Person, Runnable {                                                  
    func run() {
        print("Student run")
    }
    func study() {
        print("Student study")
    }                                            
} 
var stu: Any = 10
print(stu is Int) // true
stu = "Jack"
print(stu is String) // true 
stu = Student()
print(stu is Person) // true 
print(stu is Student) // true 
print(stu is Runnable) // true 
var stu: Any = 10
(stu as? Student)?.study() // 沒有調(diào)用study 
stu = Student()
(stu as? Student)?.study() // Student study 
(stu as! Student).study() // Student study 
(stu as? Runnable)?.run() // Student run 
var data = [Any]() 
data.append(Int("123") as Any) 

var d = 10 as Double
print(d) // 10.0   

\color{green}{X.self} \color{green}{X.Type} \color{green}{AnyClass}

  • \color{green}{X.self}是一個(gè)元類型(metadata)的指針,metadata存放著類型相關(guān)信息

  • \color{green}{X.self}屬于\color{green}{X.Type}類型

class Person {}
class Student : Person {}
var perType: Person.Type = Person.self 
var stuType: Student.Type = Student.self 
perType = Student.self 
var anyType: AnyObject.Type = Person.self 
anyType = Student.self 

public typealias AnyClass = AnyObject.Type 
var anyType2: AnyClass = Person.self 
anyType2 = Student.self 
var per = Person()
var perType = type(of: per) // Person.self 
print(Person.self == type(of: per)) // true 

\color{green}{元類型的應(yīng)用}

class Animal { required init() {} } 
class Cat : Animal {}
class Dog : Animal {}
class Pig : Animal {} 

func create(_ clses: [Animal.Type]) -> [Animal] { 
    var arr = [Animal]()
    for cls in clses {                                              
        arr.append(cls.init()) 
    }                                              
    return arr 
} 

print(create([Cat.self, Dog.self, Pig.self])) 

\color{green}{元類型的應(yīng)用}

import Foundation
class Person {
    var age: Int = 0
}

class Student : Person {
   var no: Int = 0                                              
}

 print(class_getInstanceSize(Student.self)) // 32 
 print(class_getSuperclass(Student.self)!) // Person 
 print(class_getSuperclass(Person.self)!) // Swift._SwiftObject 

\color{green}{Self

  • Self代表當(dāng)前類型
class Person {
   var age = 1
   static var count = 2
   func run() {
      print(self.age) // 1
      print(Self.count) // 2
    }                                                 
} 
  • Self一般用作返回值類型寨闹,限定返回值跟方法調(diào)用者必須是同一類型(也可以作為參數(shù)類型)
protocol Runnable {
    func test() -> Self
}

class Person : Runnable {
    required init() {}                                           
    func test() -> Self { type(of: self).init() } 
} 

class Student : Person {}

var p = Person()
// Person
print(p.test())

var stu = Student()
// Student
print(stu.test())
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市君账,隨后出現(xiàn)的幾起案子繁堡,更是在濱河造成了極大的恐慌,老刑警劉巖乡数,帶你破解...
    沈念sama閱讀 206,013評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件椭蹄,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡净赴,警方通過查閱死者的電腦和手機(jī)绳矩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來玖翅,“玉大人翼馆,你說我怎么就攤上這事割以。” “怎么了应媚?”我有些...
    開封第一講書人閱讀 152,370評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵严沥,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我中姜,道長(zhǎng)祝峻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,168評(píng)論 1 278
  • 正文 為了忘掉前任扎筒,我火速辦了婚禮,結(jié)果婚禮上酬姆,老公的妹妹穿的比我還像新娘嗜桌。我一直安慰自己,他們只是感情好辞色,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,153評(píng)論 5 371
  • 文/花漫 我一把揭開白布骨宠。 她就那樣靜靜地躺著,像睡著了一般相满。 火紅的嫁衣襯著肌膚如雪层亿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,954評(píng)論 1 283
  • 那天立美,我揣著相機(jī)與錄音匿又,去河邊找鬼。 笑死建蹄,一個(gè)胖子當(dāng)著我的面吹牛碌更,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播洞慎,決...
    沈念sama閱讀 38,271評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼痛单,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了劲腿?” 一聲冷哼從身側(cè)響起旭绒,我...
    開封第一講書人閱讀 36,916評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎焦人,沒想到半個(gè)月后挥吵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,382評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡花椭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,877評(píng)論 2 323
  • 正文 我和宋清朗相戀三年蔫劣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片个从。...
    茶點(diǎn)故事閱讀 37,989評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡脉幢,死狀恐怖歪沃,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情嫌松,我是刑警寧澤沪曙,帶...
    沈念sama閱讀 33,624評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站萎羔,受9級(jí)特大地震影響液走,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜贾陷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,209評(píng)論 3 307
  • 文/蒙蒙 一缘眶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧髓废,春花似錦巷懈、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至冈爹,卻和暖如春涌攻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背频伤。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評(píng)論 1 260
  • 我被黑心中介騙來泰國(guó)打工恳谎, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人憋肖。 一個(gè)月前我還...
    沈念sama閱讀 45,401評(píng)論 2 352
  • 正文 我出身青樓惠爽,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親瞬哼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子婚肆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,700評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 協(xié)議(Protocol) 1)協(xié)議可以用來定義方法、屬性坐慰、下標(biāo)的聲明较性,協(xié)議可以被枚舉、結(jié)構(gòu)體结胀、類遵守(多個(gè)協(xié)議之間...
    codeTao閱讀 255評(píng)論 0 1
  • 1.協(xié)議介紹 協(xié)議可以用來定義方法赞咙、屬性、下標(biāo)的聲明糟港,協(xié)議可以被枚舉攀操、結(jié)構(gòu)體、類遵守(多個(gè)協(xié)議之間用逗號(hào)隔開) 協(xié)...
    happy神悅閱讀 229評(píng)論 0 1
  • 1.可選鏈 如果可選項(xiàng)為nil歹垫,調(diào)用方法、下標(biāo)颠放、屬性失敗排惨,結(jié)果為nil 如果可選項(xiàng)不為nil,調(diào)用方法碰凶、下標(biāo)暮芭、屬性...
    一抹相思淚成雨閱讀 91評(píng)論 0 1
  • 一. 可選鏈(Optional Chaining) 什么是可選鏈?我們知道如果一個(gè)變量是 p:Person? 類型...
    Imkata閱讀 333評(píng)論 0 1
  • 一、繼承(Inheritance) 1.1野宜、類繼承值類型(枚舉扫步、結(jié)構(gòu)體) 不支持繼承,只有 類 支持繼承匈子;沒有父類...
    IIronMan閱讀 693評(píng)論 0 4