【问题标题】:Can I have a Swift protocol without functions我可以有一个没有功能的 Swift 协议吗
【发布时间】:2016-08-25 20:40:09
【问题描述】:

考虑这个典型的例子,有时会在教程等中看到 (even in Apple's code):

protocol Nameable {
     var name: String {get}
}

struct Person : Nameable {
     var name: String
}

我的问题是,这种模式有什么好处?一旦将函数添加到协议中,我就可以理解它,但是对于只有一个或多个变量的协议,什么可能是一个好的应用程序?为什么不将 name 添加到每个 struct 和 class ?

【问题讨论】:

  • 多态非常有用。您可以在不知道其实际类型的情况下使用对象。
  • @Francescu 你能详细说明一下吗?

标签: swift protocols


【解决方案1】:

Persons 不是您可能想要命名的唯一不是唯一的东西。宠物有名字,道路有名字,哎呀,有些人给他们的车起名字。

如果我们想为不同对象集合中的每个对象命名怎么办?如果我们将这些对象存储在Any 的集合中,我们就无法保证所有对象都有名称。

这就是协议的用武之地。通过创建Nameable 协议,我们可以创建Nameable 对象的集合,并确保其中的所有对象都有名称。

这是一个例子:

protocol Nameable {
    var name: String {get}
}

struct Person : Nameable {
    let name: String
    let age: Int
    // other properties of a Person
}

struct Pet : Nameable {
    let name: String
    let species: String
    // other properties of a Pet
}

struct Car : Nameable {
    let name: String
    let horsepower: Double
    // other properties of a Car
}

let namableItems: [Nameable] = [
    Person(name: "Steve", age: 21),
    Pet(name: "Mittens", species: "Cat"),
    Car(name: "My Pride and Joy", horsepower: 9000)
]

for nameableItem in namableItems {
    print("\(nameableItem.name) is a \(nameableItem.dynamicType).")
}

哪些打印:

史蒂夫是一个人。

手套是宠物。

我的骄傲和喜悦是一辆汽车。

You can try it here.

【讨论】:

  • 这与类和子类关系有何区别?为什么有人会使用其中一个?
  • @brandonscript 有时,多种类型具有某些共享功能是有意义的,但在类-子类关系中不会如此紧密地绑定。例如,许多类型是CustomStringConvertible(具有description 属性),但将它们全部子类化为单个类没有意义。使用协议还意味着您可以在完全不同的事物之间共享功能(其中许多没有子类化的概念)——结构、枚举和类都可以遵循相同的协议。
  • 这个功能更强大。继承的限制要大得多。如果我希望我的Car 成为Nameable 而不使用协议,它必须是名为AbstractNameable 的抽象类的子类。但是现在我的Car 不能再是Vehicle 的子类,因为Swift(像大多数语言一样)不支持多重继承。
  • 很好的答案和cmets!搞定了。
  • 对象在被询问时给出其答案的能力当然是一种功能
【解决方案2】:

基本上,您承诺您的类/结构将包含已定义的属性。

对于结构来说,这非常重要,因为它们不能被子类化。

另外,子类只能有 1 个超类,因此您不能创建拥有多个父类的 Person。

我建议您阅读这篇文章,了解为什么使用协议而不是子类化以及使用它们的主要目的:

http://alisoftware.github.io/swift/protocol/2015/11/08/mixins-over-inheritance/

【讨论】:

    【解决方案3】:

    答案的关键在于protocol这个词。

    协议是一个规则系统,用于解释正确的行为和 在正式情况下要遵循的程序。

    也就是说,当您声明对象(结构、枚举、类、..)必须符合协议时,您有义务强> 尊重它。如果你不这样做,Xcode 会抛出一个错误。

    因此,其中一个主要的(绝对不是唯一的实用程序)是您不能忘记在各种对象中包含属性和/或函数。

    如果多个开发人员正在处理相同的代码,或者只是为了避免分心的潜在人为错误,这可能非常有用:)。

    协议的另一个巨大优势是它们可以用作类型。

    因此,一个结构体、枚举或不同的类,它们继承了相同的协议,它们都可以追溯到相同的类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-31
      • 2019-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多