协议
如果类的所有方法都是抽象的,在Swift和Object-C中称为协议,在Java语言中称为接口,在C++中称为纯虚类;只有方法的定义没有方法的具体实现,所在的类叫抽象类
协议不能被实例化
Swift和Object-C中实现抽象类的过程称为遵守协议
一、声明和遵守协议
类、结构体和枚举类型可以声明与遵守某个协议,并提供该协议所需要的属性和方法
协议定义的语法如下:
protocol 协议名 {
//内容
}
在声明遵守协议时,格式如下:
类型 类型名:协议1,协议2 {
//遵守协议内容
}
类型包括类、结构体和枚举,冒号后面是遵守的协议,如果有多个协议,协议之间用逗号隔开
协议可以要求其遵守者提供实例属性,静态属性,实例方法和静态方法的实现,
二、协议方法
协议可以要求其遵守者实现某些指定方法,包括实例方法和静态方法,这些方法在协议中被定义,协议方法和普通方法类似,但不支持边长参数和默认值参数,也不需要大括号和方法体
1、实例协议方法
protocolFigure{funconDraw()}classRectangle:Figure{funconDraw(){println("绘制矩形")}}classCircle:Figure{funconDraw(){println("绘制圆形")}}
2、静态协议方法
在协议中定义静态方法与在类中定义静态方法一样,方法前需要添加class关键字,在遵守该协议的时候,遵守者静态方法前加class或者static,与遵守者类型有有关系,如果是类,关键字就是class,如果是结构体或枚举,关键字就是static.
protocolAccount{classfuncinterestBy(amount:Double)->Double}classClassImp:Account{classfuncinterestBy(amount:Double)->Double{return0.668*amount}}classStructImp:Account{staticfuncinterestBy(){return0.668*amount}}
3、变异方法
在结构体和枚举类型中可以定义变异方法,而在类中没有这种方法,原因是结构体和枚举中的属性是不可修改,通过定义变异方法,可以修改这些属性,而类是引用类型,不需要变种方法就可以修改自己的属性;
在协议定义变种方法时,方法前要加上mutating关键字,类、结构体和枚举都可以实现变异方法,类实现变异方法时,前面不需要加mutating关键字,结构体和枚举在实现变异方法时,前面需要加mutating关键字
protocolEditable{mutatingfuncedit()}classClassImp:Editable{varname="ClassImp"funcedit(){println("编辑ClassImp...")self.name="编辑ClassImp"}}structStructImp:Editable{varname="StructImp"mutatingfuncedit(){println("编辑StructImp")self.name="编辑StructImp"}}
structEnum:Editable{caseMondaycaseTuesdaycaseWednesdaycaseThursdaycaseFridaymutatingfuncedit(){self=.Friday}}
4、实例协议属性
协议可以要求其遵守者实现某些指定属性,包括实例属性和静态属性,在具体定义的时候,每一种属性都可以有只读和读写之分
对于遵守者而言,实例属性时市场灵活的,无论是存储属性还是计算属性,只要能通过协议属性的要求,就可以通过编译,甚至是协议中定义了只读属性,而遵守者提供了对该属性的读写,这也是被允许的,因为遵守者通过了协议的只读属性要求,协议只规定了必须要做的事情,但没有规定不能做的事情;
protocolPerson{varfirstName:String{getset}varlastName:String{getset}varfullName:String{get}}classEmployee:Person{varno:Int=0varjob:String?varsalary:Double=0varfirstName:String="Tony"varlastName:String="zhang"varfullName:String{get{return"\(firstName)\(lastName))"}set(newFullName){varname=newFullName.componentsSeperatedByString(".")self.firstName=name[0]self.lastName=name[1]}}}
三、协议属性
在协议中定义静态属性与在协议中定义静态属性类型,属性前面要加class关键字还是static,与遵守者类型有关系,如果是类,关键字是class,如果是结构体和枚举,关键字是static
protocolAccount{classvarinterestRate:Double{get}classfuncinterestBy(amount:Double)->Double}classClassImp:Account{classvarinterestRate:Double{return0.668}classfuncinterestBy(amount:Double)->Double{returnClassImp.interestRate*amount}}structStructImp:Account{staticvarinterestRate:Double=0.668staticfuncinterestBy(amount:Double)->Double{returnStructImp.interestRate*amount}}
四、把协议作为类型使用
虽然协议没有具体的实现代码,不能被实例化,但它的存在是为了规范其遵守者而设计的,它是面向接口编程必不可少的机制,面向接口编程的系统的定义与实现应该分离,协议作为数据类型暴露给使用者,使其不用关心具体的实现细节,从而提供系统的扩展性和复用性;
在Swift中,协议作为数据类型使用,它可以出现在任意允许数据类型出现的地方:
protocolPerson{varfirstName:String{getset}varlastName:String{getset}varfullName:String{get}fundescription()->String}classStudent:Person{varschool:StringvarfirstName:StringvarlastName:StringvarfullName:String{returnself.firstName+self.lastName}funcdescription()->String{returnself.firstName+self.lastName+self.school}init(firstName:String,lastName:String,school:String){self.firstName=firstNameself.lastName=lastNameself.schooll=school}}
五、协议的继承
一个协议继承就像是类继承一样:
protocolPerson{varfirstName:String{getset}varlastName:String{getset}varfullName:String{get}fundescription()->String}
protocolStudent:Person{varschool:String}classGraduate:Student{}
六、协议的合成
多个协议可以临时合并成一个整体,作为一个类型使用,首先要有一个类型在声明时遵守多个协议
protocolShip{vardisplacement:Double{getset}}protocolWeapon{vargunNumber{getset}}classWarShip:Ship,Weapon{vardisplacement=100000.00vargunNumber=10}funcshowWarResource(resource:protocol<Ship,Weapon>){println("\(resource.displacement):\(resource.gunNumber)")}letship=WarShip()showWarResource(ship)
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。