Swift学习笔记十六:协议

it2025-06-04  74

Protocol(协议) 用于统一方法和属性的名称,而不实现不论什么功能。

协议 可以被类。枚举。结构体实现。满足协议要求的类,枚举,结构体被称为协议的 遵循者 遵循者 须要提供 协议 指定的成员,如属性,方法,操作符,下标等。 一、协议的基本的语法

     咱们还是先上代码吧

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

最新回复(0)