(一)协议概念
协议主要用来规定统一的方法和属性名称,但是不实现任何功能。只有实现了协议的类才需要实现他的功能。
(二)协议
协议的定义语法:
protocol 协议名 {
//协议内容
}
声明遵从协议时的语法:
类型 类型名: 协议1,协议2 {
//遵从协议内容
}
其中类型包括Class、struct和enum,类型名由我们自己定义,冒号(:)后是需要遵从的协议。当要遵从多个协议时,各协议之间用逗号(,)隔开。如果一个类继承父类的同时也要遵从协议,应当把父类放在所有的协议之前。
class 类名:父类,协议1,协议2 {
//遵从协议内容
}
注:只有类的定义会有父类和协议混合声明,结构体和枚举是没有父类型的。
(三)协议方法 :
协议可以要求其遵从者实现某些指定方法,包括实例方法和静态方法。
协议实例方法定义与遵从:
protocol Figure {
func onDraw() //定义抽象绘制几何图形
}
class Rectangle: Figure {
func onDraw() {
print("绘制矩形...")
}
}
class Circle: Figure {
func onDraw() {
print("绘制圆形...")
}
}
let rect: Figure = Rectangle()
rect.onDraw()
let circle : Figure = Circle()
circle.onDraw()
协议静态方法:
在协议中定义静态方法时前面要添加static关键字。如果遵从者是结构体或枚举,关键字是static;如果遵从者是类,关键字可以是class或static。使用class遵从者的子类可以重写该静态方法,使用static遵从者的子类不可以重写该静态方法。
protocol Account {
static func interestBy(amount:Double)->Double
class ClassImp:Account {
class func interestBy(amount:Double)->Double {
return 0.0668*amount
}
}
struct StructImp:Account {
static func interestBy(amount:Double)->Double {
return 0.0668*amount
}
}
enum EnumImp: Account {
static func interestBy(amount:Double)->Double{
return 0.0668*amount
}
}
协议变异的方法:
在结构体和枚举类型中可以定义变异方法,而在类中没有这种方法。在协议定义变异方法时,方法前面要添加mutating关键字。
protocol Editable {
mutating func edit()
}
class ClassImp:Editable {
var name = "ClassImp"
func edit() {
print("编辑ClassImp...")
self.name = "编辑ClassImp..."
}
}
struct StructImp:Editable {
var name = " StructImp"
mutating func edit() {
print("编辑StructImp...")
self.name = "编辑StructImp..."
}
}
enum EnumImp: Editable {
case Monday
case Tuesday
case Wednesday
case Thursday
case Friday
mutating func edit() {
print("编辑EnumImp...")
self = .Friday
}
}
var classInstance:Editable = ClassImp()
classInstance.edit()
var structInstance:Editable = StructImp()
structInstance.edit()
var enumInstance: Editable = EnumImp.Monday
enumInstance.edit()
(四)协议属性
协议可以要求其遵从者实现某些指定属性,包括实例属性和静态属性。在具体定义的时候,每一种属性都可以有只读和读写之分。
协议实例属性:
protocol Person {
var firstName:String{get set}
var lastName:String{get set}
var fullName:String{get}
}
class Emloyee:Person {
var no:Int=0
var job:String?
var salary:Double = 0
var firstName:String = "Tony"
var lastName:String = "Guan"
var fullName:String {
get {
return self.firstName+"."+self.lastName
}
set (newFullName) {
var name = newFullName.componentsSeparatedByString(".")
self.firstName = name[0]
self.lastName = name[1]
}
}
}
协议静态属性:
在协议中定义静态属性与在协议中定义静态方法类似,前面要添加static关键字。
protocol Account {
static var interestRate:Double {get} //利率
static func interestBy(amount:Double)->Double
}
class ClassImp:Account {
static var interestRate:Double {
return 0.0668
}
class func interestBy(amount:Double)->Double{
return ClassImp.interestRate*amount
}
}
struct StructImp:Account {
static var interestRate:Double = 0.0668
static func interestBy(amount:Double)->Double{
return StructImp.interestRate*amount
}
}
enum EnumImp:Account {
static var interestRate:Double = 0.0668
static func interestBy(amount:Double)->Double {
return EnumImp.interestRate*amount
}
}
(五)面向协议编程
协议类型:
协议类型可以作为函数、方法或构造函数中的参数类型或返回值类型;
协议类型 可以作为常量、变量或者属性的类型;
协议类型可以作为数组、字典和set等集合的元素类型 。
协议的继承:
协议间的继承与类继承一样
协议扩展
协议的合成:
多个协议可以临时合成一个整体,作为一个类型使用。首先要有一个类型在声明时遵从多个协议。
扩展中遵从协议