咱们还是先上代码吧
protocol Human { var name:String{ get set } var isMan:Bool{set get} class var isUsable:Bool { set get } //类成员。表示这个类是否可用 func ageDescription(ages:Int...) //函数參数能够是变长參数 } class Student{ var name = "" } class PrimaryStudent:Student,Human{ class var isUsable:Bool{ get{ return self.isUsable } set{ self.isUsable = newValue } } var isMan:Bool init(name:String,isMan:Bool){ self.isMan = isMan super.init() self.name = name } func ageDescription(ages:Int...){ var ageCount = 0 for age in ages{ ageCount += age; } println("this man age is \(ageCount)") } } 重点: ① 遵守某个协议须要像继承一样。在:后面加入这个协议 ② 假设既要继承又要遵守协议,须要把继承的父类放在最前面 ③ 对于协议中的属性,须要标明属性的读写类型,能够是读写或者仅仅读(不能仅仅写不读) ④ 对于类成员,须要在协议中的属性前面加 class keyword,假设是类遵守协议加 class keyword,假设是枚举或者结构体遵守协议加 static keyword ⑤ 协议中方法支持变长參数,但不支持參数默认值 二、协议类型 虽然 协议 本身并不实现不论什么功能,可是 协议 能够被当做类型来使用。 使用场景: 协议类型 作为函数、方法或构造器中的參数类型或返回值类型 协议类型 作为常量、变量或属性的类型 协议类型 作为数组、字典或其它容器中的元素类型
protocol RandomNumberGenerator { func random() -> Double } class Dice { let sides: Int let generator: RandomNumberGenerator init(sides: Int, generator: RandomNumberGenerator) { self.sides = sides self.generator = generator } func roll() -> Int { return Int(generator.random() * Double(sides)) + 1 } } class LinearCongruentialGenerator: RandomNumberGenerator { func random() -> Double { return random()%10.0 } } var d6 = Dice(sides: 6,generator: LinearCongruentialGenerator()) 解释: 在Dice中。 generator是 RandomNumberGenerator 协议类型。
所以仅仅能使用遵守
RandomNumberGenerator 协议的类、结构体、枚举类型给他赋值。在后面我们能够看到,在初始化的时候使用遵守 RandomNumberGenerator 协议的 LinearCongruentialGenerator 给他赋值了 三、托付代理模式 玩过Objective-C的朋友相比对托付代理非常熟悉了,Swift中的托付代理和OC的大同小异,我们还是来看看代码吧protocol NameComplete { func nameSetCompleted(theName:String) } class Student{ var delegate:NameComplete? var name:String{ didSet{ self.delegate?.nameSetCompleted(name) } } init(name:String,delegate:NameComplete){ self.name = name self.delegate = delegate } } class DoSth:NameComplete{ func nameSetCompleted(theName:String){ println("name:\(theName) is set ") } } var a = DoSth() var b = Student(name:"",delegate:a) b.name = "小笨狼" //输出:name:小笨狼 is set 解释: NameComplete是一个代理。DoSth遵从并实现这个代理,Student调用代理。
在Student中name被赋值之后,代理中nameSetCompleted方法会被调用
三、可选协议 玩过OC的朋友知道。OC中协议有的方法是可选的。在Swift中协议也有这个功能,以下我们来看看@objc protocol Human{ @optional var name:String{get set} @optional func descript() } class Student:Human{ var name:String = "abc" func descript(){ println("abc") } } 重点: ① 对于可选方法或者属性。须要在方法或者属性前加上 @optional keyword ② 假设协议中含有可选方法或者属性,在定义协议时须要在 protocol 前加上 @objc keyword ③ 在可选协议中,不能出现OC没有的类型。比方变长类型 ④ 可选协议仅仅能被类遵从 四、协议继承 协议和类一样。也能够继承
protocol pName{ var name:String{set get} } protocol dName:pName{ func descript() } class Human:dName{ var name = "" func descript(){ println(name) } } 解释: dName 继承了 pName ,所以 dName 协议不仅含有一个 descript 方法还含有 name 属性,所以遵从 dName 协议的类必须有 name 属性和 descript 方法 五、协议合成
protocol Named { var name: String { get } } protocol Aged { var age: Int { get } } struct Person: Named, Aged { var name: String var age: Int } func wishHappyBirthday(celebrator: protocol<Named, Aged>) { println("Happy birthday \(celebrator.name) - you're \(celebrator.age)!") } let birthdayPerson = Person(name: "Malcolm", age: 21) wishHappyBirthday(birthdayPerson) //输出Happy birthday Malcolm - you're 21! 解释: wishHappyBirthday 方法传入的參数是 < Named , Aged > 合成协议类型,这时能够传入遵从这2个协议的结构体的实例 注意: 协议合成并非生成一个新协议。而是多个协议合成一个暂时协议,超出范围后就会失效
转载于:https://www.cnblogs.com/bhlsheji/p/5326538.html