来自Apple自己的网站:" Swift设计的核心是两个非常强大的想法:面向协议的编程和一流的价值语义。 #34;
有人可以详细说明什么是面向协议的编程,它带来了什么附加价值?
我已阅读this并观看了Swift video中的面向协议编程,但来自Objective-C背景仍然无法理解。我恳请一个非常简单的英语答案以及代码片段&关于它与Objective-C的不同之处的技术细节。
只是我所使用的混淆中的一个 <tableViewDelegate, CustomDelegate>
我们也不能符合Objective-C中的多个协议吗?那么Swift又是如何新的?
编辑:请参阅Protocol-Oriented Views视频。我发现这个视频更基本,更容易掌握一个有意义的用例。 WWDC视频本身有点先进,需要更广泛的视野。此外,这里的答案有点抽象。
答案 0 :(得分:31)
前言:POP和OOP不是互斥的。他们的设计范式非常相关。
POP over OOP的主要方面是更喜欢composition over inheritance。这有几个好处。
在大型继承层次结构中,祖先类倾向于以包含大多数(通用)功能,而叶子类只产生最小的贡献。这里的问题是祖先类最终会做很多事情。例如,一个Car
驱动器,存储货物,安排乘客,播放音乐等。这些是许多功能,每个功能都非常不同,但它们都不可分割地归入Car
类。 Car
的后代,例如Ferrari
,Toyota
,BMW
等,都对此基类进行了少量修改。
这样做的结果是减少了代码重用。我的BoomBox
也播放音乐,但它不是汽车。 1}}继承音乐播放功能是不可能的。
Swift鼓励的是,这些庞大的整体类被分解为更小的组件。然后可以更容易地重用这些组件。 Car
和Car
都可以使用BoomBox
。
Swift提供了多种功能来实现这一目标,但到目前为止最重要的是协议扩展。它们允许协议的实现与其实现类分开存在,因此许多类可以简单地实现该协议并立即获得其功能。
答案 1 :(得分:9)
在Objective C协议中,与大多数语言中的接口相同。因此,在Objective C协议中,使用仅限于SOLID原则&#34; 依赖于抽象。不要依赖于结核。&#34;
在Swift中,协议的改进非常严重,因为它们仍然可以用作接口,实际上它们更接近类(如C ++中的Abstract classes)
在Objective C中,在类之间共享功能的唯一方法是继承。并且您可以继承唯一的一个父类。在Swift中,你也可以采用任意数量的协议。由于Swift中的协议可以使用默认方法实现,因此它们为我们提供了一个功能齐全的Multiple inheritance。更灵活,更好的代码重用 - 太棒了!
<强>结论:强>
面向协议的编程与 OOP 大致相同,但它不仅通过继承而且通过协议采用(Composition over inheritance)进一步关注功能共享。
值得一提的是,在C ++中,抽象类与Swift中的协议非常相似,但没有人说C ++支持某种特定类型的OOP。因此,在 general 中,如果我们谈论编程范例,POP就是OOP的一个版本。对于Swift,POP是OOP的改进版本。
答案 2 :(得分:8)
令我感到惊讶的是,没有一个答案提到POP中的值类型。
要了解什么是面向协议的编程,您需要了解面向对象编程的缺点。
在swift中面向协议的编程中:
因此,面向协议的编程只不过是另一种尝试解决OOP缺点的编程范式。
答案 3 :(得分:4)
添加上述答案
协议是一个接口,其中声明方法和属性的签名,并且枚举枚举的任何class / struct / enum必须遵守合同意味着它们必须实现声明的所有方法和属性在超类协议中。
使用协议的原因
类提供单继承,而struct不支持继承。因此引入了协议。
扩展协议内部声明的方法可以在扩展内部实现,以避免在具有相同方法实现的多个类/结构中继承协议的情况下代码的冗余。我们可以通过简单地声明struct / enums的对象来调用该方法。即使我们可以将扩展限制为类列表,只有受限类才能使用扩展内部实现的方法,而其余的类必须在自己的类中实现方法。
示例强>
protocol validator{
var id : String{ get }
func capitialise()-> (String)
}
extension validator where Self : test{
func capitialise() -> String{
return id.capitalized
}
}
class test : validator {
var id: String
init(name:String) {
id = name
}
}
let t = test(name: "Ankit")
t.capitialise()
何时使用在OOP中假设我们有一个由飞机,自行车,汽车等继承的车辆基类。这里打破,加速可能是三个子类中的常用方法,但不是可飞行方法飞机因此,如果我们也在OOP中声明可飞行方法,那么自行车和汽车子类也具有继承可飞行方法,这对于那些类没用。因此在POP中我们可以声明两个协议,一个用于可飞行对象,另一个用于中断和加速方法。可飞行协议可以限制仅由飞机使用
答案 4 :(得分:0)
面向协议的编程(POP)