我们先来定义一个Person协议
protocol Person{
var name:String {get}
var age:Int {get}
func personInfo() -> ()
}
先来定义一个Teacher类
class Teacher:Person{
//这里,我把name,age都变成了可读可写的属性这样写,就需要一个构造函数了
var name: String
var age: Int
init(name:String, age:Int) {
self.name = name
self.age = age
}
func personInfo() {
print(name, "的年龄是", age)
}
}
我们还有一个Student类
class Student:Person{
var name: String
var age: Int
init(name:String, age:Int) {
self.name = name
self.age = age
}
func personInfo() {
print(name, "的年龄是", age)
}
}
使用的时候
var xiaoming = Teacher(name: "小明", age: 25)
xiaoming.personInfo()
var xiaohua = Student(name: "小花", age: 30)
xiaohua.personInfo()
我们发现,其实personInfo这个函数实现逻辑都是一样的,如果类很多,那么就会有很多重复的逻辑,但是协议里边又不能写函数的实现部分,想解决这个问题,很简单,扩展一下协议就行
extension Person{
func personInfo(){//这里,如果遵循协议的类没有实现这个方法,就会走默认的这个,当然,类也可以覆盖这个方法,个性化的实现
print(name, "的年龄是", age)
}
}
扩展了协议之后,我们再Teacher,Student类里边,就不用再写personInfo这个函数了。
协议扩展,可以写方法实现,也可以扩展属性,比如我们要计算一个人还有多少年退休,在协议扩展里写一个get-only的计算属性
var retireDistanceYear:Int{
return 60 - age
}
就可以这样来得到距离退休的还有多少年
var xiaoming = Teacher(name: "小明", age: 25)
xiaoming.retireDistanceYear
这里,协议就打破了只能写接口不能写逻辑的限制,所以就有了一个所谓的面向协议的编程,对比面向对象编程,可以理解为协议替代了对象,面向对象,就是对象来处理逻辑,实现功能,而面向协议就是一个对象如果想实现什么功能,直接遵循实现相关功能的协议就行,相比面向对象,更加灵活。
来一个例子
面向对象就是,一个武器库,每个武器都是一个对象,你想要什么功能,直接拿对应的武器就可以,因为功能已经在武器里封装好了
面向协议就是,有一个发射器,可以发射各种炮弹,每种炮弹都是一个协议,想要什么样的功能,拿相应的炮弹就行
网友评论