协议类似于Java的接口,语法
protocol 协议名 {
}
属性
protocol Person {
// 可读可写属性
var name: String { set get }
// 可读属性
var age: Int { get }
}
实现协议和继承一样,使用“ : ”
class ITPerson: Person {
// 符合Person协议属性
var age: Int
// 符合Person协议属性
var name: String
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
我尝试去设置age属性的值,好像也没有报错,不知道这个 { get set } 是不是只是一个形式上的约定??总之编译器没有报错。
方法
我们在协议定义方法时,和Java接口一样,不做任何实现
protocol Person {
var name: String { get set }
// 定义协议方法
func sayHello(greet: String)
}
class ITPerson: Person {
var name: String
init(name: String) {
self.name = name
}
// 实现Person协议方法
func sayHello(greet: String) {
print("\(greet), \(self.name)")
}
}
let johan = ITPerson(name: "Johan")
johan.sayHello(greet: "hello")
如果方法需要给值类型(结构体,枚举)修改属性值的话,需要在方法前加“mutating”关键字,和函数一样,子类实现协议的方法也要带上这个关键字。
构造器
在协议中,可以定义构造器,子类实现拥有构造器的协议时,构造器类型必须是“required”,属于必要构造器,因为子类要实现协议的任何东西。
协议可以继承协议
protocol 子协议: 协议 {
}
类 类型专属协议
类类型协议指明只能由类去实现,如果结构体实现类类型专属协议,编译器会报错
protocol 协议: class {
}
检查一致性
有3个关键字:is,as?,as!
is:判断实例是否符合某个协议
as?:返回可选类型,如果实例符合协议,则返回协议的可选值,否则返回nil
as!:强制转为某个协议类型,如果不能强转,将会崩溃