Swift入门教程16-协议

协议(Protocol) 
一、定义
  用于定义完成某项任务或功能所必须的方法和属性,协议实际上并不提供这些功能或任务的具体 实现
(Implementation) --而只用来描述这些实现应该是什么样的。类,结构体,枚举通过提供协议所要求的方法,属性的具体实现来 采用(adopt) 协议。任意能够满足协议要求的类型被称为协议的 遵循者 。
  协议可以要求其遵循者提供特定的实例属性,实例方法,类方法,下标脚本,操作符等。
简单来讲:协议就是告诉编译器,这个类实现了这些属性和方法,可以进行调用。告诉用户,解决这一类问题,需要定义这些属性,实现这些方法。


二、语法
定义一个协议
protocol SomeProtocal{


}

采用一个协议
class hwcClass:SomeProtocal{

}
同时具有继承关系和遵循一个协议
class hwcSubClass:hwcSuperClass,FirstProtocal,SecondProtocal{


}
三、协议对属性的规定
  协议可以规定其属性提供特定名称特定类型的属性(类属性和实例属性均可),同时可以指定其读写全权限。采用协议的类,对应提供的属性的读写权限应该和协议一致。
协议中用{get set}表示读写,用{get}表示只读
举例
<pre name="code" class="plain">enum HwcDeviceState{
	case One
	case Off
	case Unknown
}
protocol DeviceStateProtocol{
	var state:HwcDeviceState{get set}
}
class BlueTooth:DeviceStateProtocol{
	var state:HwcDeviceState //提供协议需要提供的属性
	init(state:HwcDeviceState){
		self.state = state
	}
}
class Wifi:DeviceStateProtocol{
	var state:HwcDeviceState //提供协议需要提供的属性
	init(state:HwcDeviceState){
		self.state = state
	}
}
 
备注:这里有同学会问,那我为什么不干脆自己定义这个东西?以上述为例,我定义好了一个DeviceStateProtocol协议,那么你只要知道,所有涉及到Device的时候,遵循这个协议即可,编译器会提示你,遵循这个协议你应该实现什么东西,上述类中就是device的实例必须要提供给用户一个state查看当前设备的状态。也就是定义了解决一类问题的方法。 
四、对方法的规定协议可以要求遵循者实现某些指定的方法,这些方法包括类方法和实例方法。 
注意:协议中的方法不支持参数默协议中类方法用class关键词声明,结构体全局方法用static关键词声明举例:定义一个协议,协议要求实现方法来打印出实例的描述信息 
protocol DescriptionProtocol{
	func printDescription()
}
class NameClass:DescriptionProtocol{
	var name:String?
	func printDescription(){
		println(name)
	}
}
class CarClass:DescriptionProtocol{
	var ID:String?
	func printDescription(){
		println(ID)
	}
}
这里看到了,Name类和Car类都可以实现这个协议来打印出描述信息,这也就体现出了协议和继承的区别:协议解决的是提供解决一类抽象问题的解决方案,但是实现由具体的类决定,这些类之间可以毫无关系,只要他们都涉及到了这个抽象的解决方案。

五、mutating方法的规定
简单说下mutating方法:对于结构体和枚举,由于是值类型,所以方法不能直接修改属性的值。但是加上mutating关键词之后,就可以修改。
注意:类实现mutating方法时候,不需要该关键字,因为类本身就可以修改。但是枚举和结构体需要。
举例:
//协议用来切换状态
protocol Togglable {
	mutating func toggle()
}
//遵循该协议
enum OnOffSwitch: Togglable {
	case Off, On
	mutating func toggle() {
		switch self {
			case Off:
				self = On
			case On:
				self = Off
		}	
	}
}
var lightSwitch = OnOffSwitch.Off
lightSwitch.toggle()
六、对构造器的规定
协议要求遵循某协议的类型实现特定的构造器。
protocol SomeProtocol {
	init(someParameter: Int)
}
遵循该协议后,实现的对应构造器必须加上required关键字,required关键字保证一旦有类继承实现对应协议的类,那么子类也要提供相应的构造器。如果类不能为继承(用final修饰),则不需要该关键字
class SomeClass: SomeProtocol {
	required init(someParameter: Int) {
	//构造器实现
	}
}
七、协议类型
协议本身不实现任何事情,但是协议可以当做类型来使用。
几种情形:
1.协议作为函数的参数或者返回值
2.作为常量、变量或者属性的类型
3.作为数组、字典或者其他容器的类型
例如
protocol DescriptionProtocol{
	func printDescription()
}
class NameClass:DescriptionProtocol{
	var name:String
	func printDescription(){
		println(name)
	}
	init(name:String){
		self.name = name
	}
}
class CarClass:DescriptionProtocol{
	var ID:String
	func printDescription(){
		println(ID)
	}
	init(id:String){
		self.ID = id
	}
}
class HwcTestClass{
	var hwcDescription:DescriptionProtocol
	init(desc:DescriptionProtocol){
		self.hwcDescription = desc
	}
	func print(){
		hwcDescription.printDescription()
	}
}


 使用的时候 
var carInstance = HwcTestClass(desc:CarClass(id:"as1234"))
carInstance.print()
是不是和以父类指针为参数,传入子类指针相似呢?
比如你有一个类,你需要实现一个抽象解决方案,但是具体这个方法的实现并不知道,这时候就可以把这个抽象方法作为协议类型的参数保存起来,
等到用户实现这个类的时候,指明由那个协议的遵循着来实现这个方法。
协议在IOS开发中,绝大部分情况下还是用于Delegate和DataSource,会在下一篇进行讲解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值