如果类的所有方法都是抽象的,在Swift和Object-C中称为协议,在Java语言中称为接口,在C++中称为纯虚类;只有方法的定义没有方法的具体实现,所在的类叫抽象类
协议不能被实例化
Swift和Object-C中实现抽象类的过程称为遵守协议
一、声明和遵守协议
类、结构体和枚举类型可以声明与遵守某个协议,并提供该协议所需要的属性和方法
协议定义的语法如下:
protocol 协议名 {
//内容
}
在声明遵守协议时,格式如下:
类型 类型名:协议1,协议2 {
//遵守协议内容
}
类型包括类、结构体和枚举,冒号后面是遵守的协议,如果有多个协议,协议之间用逗号隔开
协议可以要求其遵守者提供实例属性,静态属性,实例方法和静态方法的实现,
二、协议方法
协议可以要求其遵守者实现某些指定方法,包括实例方法和静态方法,这些方法在协议中被定义,协议方法和普通方法类似,但不支持边长参数和默认值参数,也不需要大括号和方法体
1、实例协议方法
protocol Figure { func onDraw() } class Rectangle:Figure { func onDraw(){ println("绘制矩形") } } class Circle:Figure { func onDraw(){ println("绘制圆形") } }
2、静态协议方法
在协议中定义静态方法与在类中定义静态方法一样,方法前需要添加class关键字,在遵守该协议的时候,遵守者静态方法前加class或者static,与遵守者类型有有关系,如果是类,关键字就是class,如果是结构体或枚举,关键字就是static.
protocol Account { class func interestBy(amount:Double)->Double } class ClassImp:Account { class func interestBy(amount:Double)->Double { return 0.668 * amount } } class StructImp:Account { static func interestBy(){ return 0.668 * amount } }
3、变异方法
在结构体和枚举类型中可以定义变异方法,而在类中没有这种方法,原因是结构体和枚举中的属性是不可修改,通过定义变异方法,可以修改这些属性,而类是引用类型,不需要变种方法就可以修改自己的属性;
在协议定义变种方法时,方法前要加上mutating关键字,类、结构体和枚举都可以实现变异方法,类实现变异方法时,前面不需要加mutating关键字,结构体和枚举在实现变异方法时,前面需要加mutating关键字
protocol Editable { mutating func edit() } class ClassImp:Editable{ var name = "ClassImp" func edit(){ println("编辑ClassImp...") self.name = "编辑ClassImp" } } struct StructImp:Editable { var name = "StructImp" mutating func edit(){ println("编辑StructImp") self.name = "编辑StructImp" } }
struct Enum:Editable { case Monday case Tuesday case Wednesday case Thursday case Friday mutating func edit(){ self = .Friday } }
4、实例协议属性
协议可以要求其遵守者实现某些指定属性,包括实例属性和静态属性,在具体定义的时候,每一种属性都可以有只读和读写之分
对于遵守者而言,实例属性时市场灵活的,无论是存储属性还是计算属性,只要能通过协议属性的要求,就可以通过编译,甚至是协议中定义了只读属性,而遵守者提供了对该属性的读写,这也是被允许的,因为遵守者通过了协议的只读属性要求,协议只规定了必须要做的事情,但没有规定不能做的事情;
protocol Person { var firstName:String{get set} var lastName:String {get set} var fullName:String{get} } class Employee:Person { var no:Int = 0 var job:String? var salary:Double = 0 var firstName:String = "Tony" var lastName:String = "zhang" var fullName:String { get { return "\(firstName)\(lastName))" } set(newFullName){ var name = newFullName.componentsSeperatedByString(".") self.firstName=name[0] self.lastName=name[1] } } }
三、协议属性
在协议中定义静态属性与在协议中定义静态属性类型,属性前面要加class关键字还是static,与遵守者类型有关系,如果是类,关键字是class,如果是结构体和枚举,关键字是static
protocol Account { class var interestRate:Double {get} class func interestBy(amount:Double)->Double } class ClassImp:Account{ class var interestRate:Double { return 0.668 } class func interestBy(amount:Double)->Double{ return ClassImp.interestRate * amount } } struct StructImp:Account { static var interestRate:Double = 0.668 static func interestBy(amount:Double)->Double { return StructImp.interestRate * amount } }
四、把协议作为类型使用
虽然协议没有具体的实现代码,不能被实例化,但它的存在是为了规范其遵守者而设计的,它是面向接口编程必不可少的机制,面向接口编程的系统的定义与实现应该分离,协议作为数据类型暴露给使用者,使其不用关心具体的实现细节,从而提供系统的扩展性和复用性;
在Swift中,协议作为数据类型使用,它可以出现在任意允许数据类型出现的地方:
protocol Person { var firstName:String{get set} var lastName:String {get set} var fullName:String{get} fun description()->String } class Student:Person { var school:String var firstName:String var lastName:String var fullName:String { return self.firstName + self.lastName } func description()->String { return self.firstName+self.lastName+self.school } init(firstName:String,lastName:String,school:String){ self.firstName = firstName self.lastName = lastName self.schooll = school } }
五、协议的继承
一个协议继承就像是类继承一样:
protocol Person { var firstName:String{get set} var lastName:String {get set} var fullName:String{get} fun description()->String }
protocol Student:Person { var school:String } class Graduate:Student{ }
六、协议的合成
多个协议可以临时合并成一个整体,作为一个类型使用,首先要有一个类型在声明时遵守多个协议
protocol Ship { var displacement:Double {get set} } protocol Weapon { var gunNumber{get set} } class WarShip:Ship,Weapon{ var displacement = 100000.00 var gunNumber = 10 } func showWarResource(resource:protocol<Ship,Weapon>){ println("\(resource.displacement):\(resource.gunNumber)") } let ship = WarShip() showWarResource(ship)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。