协议定义了一个蓝图,规定了用来实现某一特定工作或者功能所必需的方法和属性。类,结构体或枚举类型都可以遵循协议,并提供具体实现来完成协议定义的方法和功能。任意能够满足协议要求的类型被称为遵循(conform)这个协议。
协议定义,协议中的属性需求,协议中的方法需求
//土豪修别墅,看看如何使用协议
@objc protocol Villa{
//土豪朋友必须知道有多少层,实例属性
var floors: Int {get}
//土豪朋友必须知道要什么风格,实例属性
var style: String {get}
//别墅必须有门可以打开,实例方法
func openGate() -> String
//别墅必须要有空调
func openAirCondition() -> Bool
//别墅有个狗窝更好
optional func hasDogHouse() -> Bool
}
//土豪朋友以前也是码农,虽然改了别墅,但也必须要有一个工作室写程序
protocol Workshop:class{
//必须要有桌子
var desk: String {get set}
//必须要有一本编程书籍
var book: String {get}
//可以编写程序
func program(code: String) -> Bool
//可以调试
func debug()
}
//码农离不开两样东西,电脑和游戏,必须要有游戏屋
protocol GameRoom{
var games: String {get}
}
//最终土豪朋友拿着这份组合协议的要求去招标
protocol CombineRequirement: Villa,Workshop{
//这里不能够使用class,类属性
static var name: String {get}
//在协议中声明类方法,仍然要使用static关键字。
static func finish() -> Bool
}
//实现了别墅建设要求的组合协议
class 别墅: CombineRequirement{
@objc let floors = 4
@objc var style:String{
return "全欧式建筑"
}
@objc func openGate() -> String {
return "全自动门,自由打开!"
}
@objc func openAirCondition() -> Bool {
return true
}
var desk: String{
get{
return "码农专办公室"
}
set{
print("新的值为:\(newValue)")
}
}
var book = "编程玩转 Swift"
func program(code: String) -> Bool {
print("土豪哥写的Swift程序:\(code)")
return true
}
func debug() {
print("调试通过哦!")
}
class var name: String{
return "别墅"
}
class func finish() -> Bool {
return true
}
}
上述代码分析:1:协议定义的几种格式:
普通格式: protocol 协议名称 {协议体} 如:protocol GameRoom{协议体}
继承格式:protocol 协议名称:协议1,协议2,...{协议体}如:protocol CombineRequirement: Villa,Workshop{协议体}
类特定协议格式1:@objc protocol 协议名称 {协议体} 如:@objc protocol Villa{协议体}
类特定协议格式2:protocol 协议名称: class {协议体} 如:protocol Workshop:class{协议体}
注意点:
要使类遵循某个协议,需要在类型名称后加上协议名称,中间以冒号:分隔,作为类型定义的一部分。遵循多个协议时,各协议之间用逗号,分隔。
class SomeClass: FirstProtocol, AnotherProtocol {
// 类的内容
}
如果类在遵循协议的同时拥有父类,应该将父类名放在协议名之前,以逗号分隔。
class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol {
// 类的内容
}
2:协议也是一种类型,就像String,Enum一样,所以我们定义协议名时,首字母应大写,遵守命名规范.
3:关于协议中的属性需求,如下:
1)协议中描述属性需求时,必须使用var.
2)遵守类型实现协议属性需求时,不能够改变属性的名字和类型,比如Villa中的style,在其遵守类型中不能改为其他名字或者类型,否则会被认为没有遵守该需求.
3)协议中的需求可以描述为实例属性,也可以是类型属性.而不指定是存储型属性(stored property)还是计算型属性(calculate property),在协议中定义类属性(type property)时,总是使用static关键字作为前缀。当协议的遵循者是类时,可以使用class或static关键字来声明类属性,但是在协议的定义中,仍然要使用static关键字。
4)属性后面的{get}表示,协议遵守类型在实现该属性需求时,既可以把该属性定义为变量var,也可以是常量let.
5)属性后面的{get set}表示,协议遵守类型在实现该属性需求时,只能够是把该属性定义为变量var,而不能够为let.
4:关于协议中的方法需求,如下:
1)既可以描述为实例方法,也可以描述为类型方法.像普通的方法一样放在协议的定义中,但是不需要大括号和方法体。可以在协议中定义具有可变参数的方法,和普通方法的定义方式相同。但是在协议的方法定义中,不支持参数默认值。
2)和属性要求一样,其遵守类型在实现方法需求时不能够改变协议方法的名称,返回值和参数必须完全匹配.
3)协议可以继承并且可以多继承,如:protocol CombineRequirement: Villa,Workshop{},CombineRequirement协议同时遵守了两个协议.
4)标准格式的协议可以被类,结构体和枚举三种类型遵守,但我们也可以通过使用"类特定协议格式1"和"类特定协议格式2"