协议语法
protocol TestProtocol{
//协议的定义部分
}
遵循协议:
struct TestStruct : TestProtocol{
//结构体定义部分
}
enum TestEnum : TestProtocol{
//枚举定义部分
}
class TestClass : TestProtocol{
//类定义部分
}
注:继承父类的类在遵循协议时,应该将继承放在协议之前。
例子:
class ChildClass : SuperClass , TestProtocol ,OtherProtocol{
//类定义部分
只能被类遵循的协议:}
协议可指定只能由类遵循,当结构体或者枚举去遵循这个协议的时候:编译报错:Non-class type "xxx" cannot conform to class protocol 'xxx'类协议例子:
协议属性:protocol ClassProtocol : class{
//协议语法
}
协议不指定属性是存储型属性还是计算型属性,它只指定属性的名称,类型和属性是可读还是可读可写(如果属性是可读可写的,那么该属性不能是常量属性或值)。
protocol TestProtocol{
var name : String {get set}
var age : Int{get}
static var testStatic : String{get set} :
}
遵循协议的简单结构体例子:
struct TestStruct : TestProtocol{
var name : String //存储型属性,协议只规定了必须要有一个可读可写的name属性,并没有要求计算型属性还是存储型属性。
var age : Int{
get{
return 12 //举例返回值
}
}
static var testStatic : String = "Swift"
}
注:协议属性指定为可读,遵循的协议可以是可读的或者可读可写的。协议属性指定为可读可写,遵循的协议只能是可读可写的。定义协议的时候只能用var来定义,协议不能像类和结构体一样用来初始化
注:可读可写性的理解:
var testStruct : TestStruct = TestStruct()
testStruct.name = "EnumJun" //可读可写,编译正常
teststruct.age = 25//可读可写,编译正常
var testProtocol : TestProtocol = TesteStruct()
testProtocol.name = "EnumJun //可读可写,编译正常
testProtocol.age = 25.//只读,编译报错:Cannot assign to property:'age' is a get-only property
协议方法:
协议可以指定遵循实例方法或者类方法。在协议的定义中,不需要大括号和方法体。可以在协议中定义具有可变参数的方法,不支持协议中的方法的参数提供默认值。
protocol FuncProtocol{
static func methodTest() //类型方法
func change() -> Double //带返回值无参的实例方法
func test(name:String, age:Int) //无返回值的实例方法
}
遵循协议的Class例子:
class FuncClass : FuncProtocol{
static func methodTest(){
//类方法实现
}
func change() ->Double{
//实例方法内部实现
return 0.0
}
func test(name:String = "EmuJun",age:Int) {
//实例方法内部实现,参数提供默认值
}
}
mutating 方法要求:
首先介绍mutating关键字:
协议中定义实例方法:在结构体和枚举中,将mutating关键字作为方法的前缀,写在func关键字之前,表示可以在该方法中修改它所属的实例以及实例的任意属性的值。如果没有这个关键字,编译报错。协议可以由类,结构体,枚举遵循,所以涉及到mutating关键字的使用。
如果需要在方法内部修改任意属性的值,定义协议时需要在方法前加mutating关键字,使得结构体和枚举能够遵循此协议并满足方法要求。
例子:
protocol MutatingProtocol{
mutating func toggle()
}
枚举遵循例子:
enum SwitchEnum : MutatingProtocol{
case Off , On
mutating func toggle()[
switch self{
case Off:
self = On //直接在func中修改属性报错,加入mutating 关键字可修改属性。
case On:
self = Off
}
}
}
结构体遵循例子:
struct MutatingStruct : MutatingProtocol{
var name : String
var age : Int
mutating func toggle(){
self.name = "EmuJun" //直接在func中修改属性报错。加上mutating关键字可修改属性。
self.age = 25
}
}
类遵循例子:
class MutatingClass : MutatingProtocol{
var name : String
var age : Int
func toggle(){
self.name = "EmuJun". //类中不需要加入mutating关键字。
self.age = 25
}
}