我可以有一个没有功能的Swift协议吗

我可以有一个没有功能的Swift协议吗,swift,protocols,Swift,Protocols,考虑这个典型的例子,有时可以在教程等()中看到: 我的问题是,这种模式的好处是什么?一旦一个函数被添加到一个协议中,我就能理解它,但是对于一个只有一个或多个变量的协议,什么样的应用程序才是好的呢?为什么不将名称添加到每个结构和类 Persons不是你唯一想命名的东西。宠物有名字,道路有名字,见鬼,有些人给他们的车起名字 如果我们想命名不同对象集合中的每个对象,该怎么办?如果我们将这些对象存储在Any的集合中,我们无法保证所有对象都有名称 这就是协议的用武之地。通过创建Nameable协议,我们可

考虑这个典型的例子,有时可以在教程等()中看到:


我的问题是,这种模式的好处是什么?一旦一个函数被添加到一个协议中,我就能理解它,但是对于一个只有一个或多个变量的协议,什么样的应用程序才是好的呢?为什么不将
名称
添加到每个
结构

Person
s不是你唯一想命名的东西。宠物有名字,道路有名字,见鬼,有些人给他们的车起名字

如果我们想命名不同对象集合中的每个对象,该怎么办?如果我们将这些对象存储在
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).")
}
其中打印:

史蒂夫是一个人

手套是宠物

我的骄傲和快乐是一辆汽车


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

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

此外,子类只能有一个超类,所以您不能创建具有多个父类的人

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


答案的关键在于“协议”一词

协议是解释正确行为和行为的规则体系 正式情况下应遵循的程序

这就是说,当您声明一个对象(结构、枚举、类等)必须符合协议时,您有义务遵守协议。否则,Xcode将抛出一个错误

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

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

协议的另一大优点是,它们可以用作类型


因此,继承相同协议的结构、枚举或不同类都可以跟踪到相同的类型。

多态性非常有用。您可以在不知道对象实际类型的情况下使用对象。@Francescu您能详细说明一下吗?这与类和子类的关系有什么区别?为什么有人会使用其中一个?@brandonscript有时,多个类型具有一些共享功能是有意义的,但在类-子类关系中没有如此紧密的约束。例如,许多类型是
CustomStringConvertible
(具有
description
属性),但将所有类型都作为单个类的子类是没有意义的。使用协议还意味着您可以在完全不同的事物(其中许多没有子类化的概念)之间共享功能—结构、枚举和类都可以遵循相同的协议。这更强大。继承要严格得多。如果我希望我的
Car
可以
Nameable
而不使用协议,那么它必须是名为
AbstractNameable
的抽象类的子类。但是现在我的
Car
不能再是
Vehicle
的子类了,因为Swift(像大多数语言一样)不支持多重继承。回答和评论很棒!!一个对象能够在被问到问题时给出自己的答案和名字,这当然是一种功能
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).")
}