[关闭]
@wrlqwe 2016-05-08T17:29:10.000000Z 字数 2326 阅读 1004

Swift的协议默认实现

Swift


继承和组合的缺点

在开发工作中,继承总是用来在多个类之间共享代码。
设想一个场景,一个人类,可以说话和睡觉,而一个Worker,除了上述功能,还可以工作。
解决方案很简单,我们可以 Person 和 Worker 之间建立继承关系:

  1. class Person {
  2. func say() {
  3. print("hello")
  4. }
  5. func sleep() {
  6. print("I'm sleeping")
  7. }
  8. }
  9. class Worker: Person {
  10. func work() {
  11. print("I'm carrying bricks")
  12. }
  13. }

在随后的开发中,可能一个新的类型 Robot,也可以工作了,这个时候我们不能使用 Worker 了,因为很明显, Robot不可能同时是一个Person。
解决这个问题,我们可能尝试组合的方式,通过公共类管理 work 行为:

  1. class WorkManager {
  2. func work() {
  3. print("I'm carrying bricks")
  4. }
  5. }
  6. class Worker: Person {
  7. let workManager = WorkManager()
  8. func work() {
  9. workManager.work()
  10. }
  11. }
  12. class Robot: Machine {
  13. let workManager = WorkManager()
  14. func work() {
  15. workManager.work()
  16. }
  17. }

这样做的缺点也显而易见,代码虽然复用了,可是类结构也变的臃肿,每次都要引用 WorkManager 。

带默认实现的协议

在Swift2.0里在定义一个协议protocol时,还能使用extension给它的某些方法做默认实现:

  1. protocol Workable {
  2. func work()
  3. }
  4. extension Workable {
  5. func work() {
  6. print("I'm carrying bricks")
  7. }
  8. }

有了上面的代码,当你创建一个遵从 Workable 协议的类或者是结构体时,就能获得 work() 方法
这只是一个默认的实现方式。因此你可以在需要的时候重新定义这个方法;如果不重新定义的话,会使用这个默认方法。
使用这种方式,可以大大简化我们的代码,我们甚至什么都不需做,指定继承关系就完成了工作:

  1. class Worker: Person, Workable {
  2. }
  3. class Robot: Machine, Workable {
  4. }
  5. ...
  6. let worker = Worker()
  7. let robot = Robot()
  8. worker.work() // I'm carrying bricks
  9. robot.work() // I'm carrying bricks

当然我们也可以设定协议依赖的数据,比如work依赖对象的名字:

  1. protocol Workable {
  2. var name: String { get }
  3. func work()
  4. }
  5. extension Workable {
  6. func work() {
  7. print("\(name) is carrying bricks")
  8. }
  9. }
  10. class Worker: Person, Workable {
  11. var name: String
  12. init(name: String) {
  13. self.name = name
  14. }
  15. }
  16. ...
  17. let worker = Worker("Tiezhu")
  18. worker.work() // Tiezhu is carrying bricks

现在可以按照功能重新划分protocol,并开启积木模式了, 首先拆分 Person :

  1. protocol Sayable {
  2. var words: String { get }
  3. func say()
  4. }
  5. extension Sayable {
  6. func say() {
  7. print("\(words)")
  8. }
  9. }
  10. protocol Sleepable {
  11. var name: String { get }
  12. func sleep()
  13. }
  14. extension Sleepable {
  15. func sleep() {
  16. print("\(name) is sleeping")
  17. }
  18. }

enjoy it :

  1. class Person: Sayable, Sleepable {}
  2. class Worker: Person, Workable {
  3. var name: String
  4. var words = "hello"
  5. init(name: String) {
  6. self.name = name
  7. }
  8. }
  9. class Robot: Sayable, Workable {
  10. var name: String
  11. var words = "..."
  12. init(name: String) {
  13. self.name = name
  14. }
  15. }
  16. class Cat: Sayable, Sleepable {
  17. var name: String
  18. var words = "meow~"
  19. init(name: String) {
  20. self.name = name
  21. }
  22. }
  23. ...
  24. let tiezhu = Worker(name: Tiezhu)
  25. tiezhu.work() // Tiezhu is carrying bricks
  26. let robot = Robot(name: T1000)
  27. robot.work() // T1000 is working
  28. let feifei = Cat(name: "feifei")
  29. feifei.say() // meow~

小结

不同于OC, Swift里大量使用了protocol, 在OC中,protocol仅限用于NSObject的子类, 而Swift则不同, protocol可以被任何类型实现,点进Swift的各个基本类型,可以看到它们都实现了各式协议,这使它们功能比其他的语言更加强大,拓展性更是如此。 Swift 的 extension 也比OC的强大的多,protocol 和 extension配合起来, 做到了更大的灵活性,实现更加强大的功能, 比起继承和组合更加有效。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注