美文网首页
Swift的协议默认实现

Swift的协议默认实现

作者: 枫叶1234 | 来源:发表于2018-04-28 14:05 被阅读48次

继承和组合的缺点

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

class Person {
    func say() { 
        print("hello")
    }
    func sleep() { 
        print("I'm sleeping")
    }
}
class Worker: Person {
    func work() { 
        print("I'm carrying bricks")
    }
}

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

class WorkManager {
    func work() { 
        print("I'm carrying bricks")
    }
}
class Worker: Person {
    let workManager = WorkManager()
    func work() { 
        workManager.work()
    }
}
class Robot: Machine {
    let workManager = WorkManager()
    func work() { 
        workManager.work()
    }
}

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

带默认实现的协议

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

protocol Workable {
  func work()
}
extension Workable {
  func work() {
    print("I'm carrying bricks")
  }
}

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

class Worker: Person, Workable {
}
class Robot: Machine, Workable {
}
...
let worker = Worker()
let robot = Robot()
worker.work() // I'm carrying bricks
robot.work() // I'm carrying bricks

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

protocol Workable {
    var name: String { get }
    func work()
}
extension Workable {
  func work() {
    print("\(name) is carrying bricks")
  }
}
class Worker: Person, Workable {
    var name: String
    init(name: String) {
        self.name = name
    }
}
...
let worker = Worker("Tiezhu")
worker.work() // Tiezhu is carrying bricks

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

protocol Sayable {
    var words: String { get }
    func say()
}
extension Sayable {
  func say() {
    print("\(words)")
  }
}
protocol Sleepable {
    var name: String { get }
    func sleep()
}
extension Sleepable {
  func sleep() {
        print("\(name) is sleeping")
  }
}

enjoy it :

class Person: Sayable, Sleepable {}
class Worker: Person, Workable {
    var name: String
    var words = "hello"
    init(name: String) {
        self.name = name
    }
}
class Robot: Sayable, Workable {
    var name: String
    var words = "..."
    init(name: String) {
        self.name = name
    }
}
class Cat: Sayable, Sleepable {
    var name: String
    var words = "meow~"
    init(name: String) {
        self.name = name
    }
}
...
let tiezhu = Worker(name: Tiezhu)
tiezhu.work() // Tiezhu is carrying bricks
let robot = Robot(name: T1000)
robot.work() // T1000 is working
let feifei = Cat(name: "feifei")
feifei.say() // meow~

小结

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

相关文章

  • Swift的协议默认实现

    继承和组合的缺点 在开发工作中,继承总是用来在多个类之间共享代码。设想一个场景,一个人类,可以说话和睡觉,而一个W...

  • swift 给protocol方法默认实现

    swift遵守协议时,需要把协议中的方法都写一遍, 可以在extension中为protocol默认实现, 协议方...

  • 54.swift的协议扩展需要特别注意的地方

    swift的协议扩展中有语法说明: 你可以使用协议扩展来给协议的任意方法或者计算属性要求提供默认实现。如果遵循类型...

  • OC协议的默认实现

    Swift 中,定义协议 protocol 时,可以使用 extension 给它的某些方法提供默认实现: 有了上...

  • OC 依赖注入 笔记

    通过默认实现协议的方法,让对象直接遵守协议就可以调用方法,有点像swift上我很喜欢的协议扩展文章地址 demo地址

  • swift里的代理协议

    swift里可以替协议默认实现,即A类定义了一个协议,然后为protocol 写一个extension,在exte...

  • 用Swift协议扩展给UICollectionView添加Hea

    Swift协议有个很强大的功能,就是通过extension给协议添加默认实现,这样就可以把公共的功能抽出来,极大的...

  • ProtocolKit 解读

    Swift支持协议方法的默认实现,而Objective-C不支持,突然想到多年前sunnyxx开源的 Protoc...

  • Swift 协议代理

    Swift 实现可选协议方法

  • swift 协议的可选方法

    在协议中定义方法 扩展协议,在扩展协议中给出默认实现 如果代理实现了此方法,会覆盖默认实现 public prot...

网友评论

      本文标题:Swift的协议默认实现

      本文链接:https://www.haomeiwen.com/subject/vadglftx.html