比较Swift中的协议与Java中的接口


149

我正在阅读Apple开发人员页面上的iOS教程。

在我看来,这protocolinterface几乎具有相同的功能。

  • 两者之间有什么区别吗?

  • 项目中的不同用法?

更新

是的,我看过上面的链接,我仍然不知道什么区别之间使用protocolinterface。当我问这样的问题时,我希望看到有关该主题的简单说明。有时很难从文档中获取所有内容。


1
Swift中的协议和Java中的接口是相同的概念。看到这里
Vivek Molkar 2015年

69
我认为像这样的关于语言之间差异的问题对于理解语言功能非常有用。而且我不认为它们会导致不必要的自以为是的答案,也不是很容易在文档中找到答案。因此,我认为在这个问题上投反对票是没有道理的。
2015年

1
这里有几个关键的现实世界的点关于Java接口- stackoverflow.com/a/41143492/294884 -这将是关键的人与斯威夫特新鲜,尝试的Java
Fattie

另一方面,令人难忘的是,Swift 的全部存在在于它是针对“面向协议的编程”的。您无所不在地使用Swift中的“协议扩展”来完成所有工作。例如,是一个关于Swift的细微问题(即:“关于协议扩展”),它说明了一些问题。
Fattie

2
在Swift中,使用协议名称,而不是使用接口名称,因为在Objective C中,来自C的头文件(无用的重复项)称为接口
Alex78191 '18

Answers:


117

本质上,协议与Java接口非常相似,除了:

  • Swift协议还可以指定必须实现的属性(即字段)
  • Swift协议需要通过使用mutating关键字来处理值/引用(因为协议可以由结构和类实现)
  • 您可以随时将协议与protocol <>关键字结合使用。例如,将必须遵守协议A和B的功能参数声明为:

func foo ( var1 : protocol<A, B> ){}

对于Java开发人员而言,这些是立即显而易见的差异(或者至少是到目前为止我发现的差异)。


13
protocol <>关键字 ”:太酷了!我认为这就是类型系统理论界中的交集类型。在Java中,只能为具有多个界限的类型参数使用此类类型。本文建议在Java中将它们作为第一类类型进行介绍,并用语法来表示它们。
2015年

7
不错的总结。几个更重要的功能:Swift协议还可以指定关联的类型要求-例如,集合类型具有关联的索引类型,或者可比较类型的比较方法需要相同类型的参数。在Swift 2.0中,协议扩展可以为满足协议要求的类型添加实际功能。
rickster

2
@rickster Java 8也可以通过使用default 关键字标记方法来向接口添加实现。请参阅《Oracle教程》
罗勒·布尔克

5
现在已删除了protocol <>关键字,以支持&符。所以你可以这样写:让c:A和B
Paul Robinson

2
在Swift中,使用协议名称,而不是使用接口名称,因为在Objective C中,来自C的头文件(无用的重复项)称为接口
Alex78191 '18

33

补充@Thomas Schar的答案。Swift协议魔术来自扩展。

  • Swift协议可以通过扩展(Swift
    2)获得实现。Java 8接口可以具有默认实现,但是不能“追溯地”完成。
  • 在Swift中,您可以“追溯地”将协议要求(
    及其实现,如果需要)添加到任何类或结构中。
  • Swift协议不遵循通用(即<..>)自定义模式,而是遵循类型别名方案(即,关联类型)。一开始可能会造成混淆,但
    在某些情况下可以避免“尖括号盲”。
  • Swift具有先进的类型模式匹配功能,可以非常明确地说明在何处以及如何应用协议要求和扩展。当来自Java时,它可能会令人困惑,但是它具有很多功能。
  • 可以为属性/参数组成快速协议(即,主持人:协议)

我花了几个小时摸索的一件事是,并非所有协议都可以用作属性类型。例如,如果您有一个带有类型别名的协议,则不能直接将其用作属性类型(考虑它是有意义的,但是从Java来的话,我们确实希望拥有诸如userDao:IDao之类的属性)。


7
与Java接口不同,Swift协议也可以具有可选成员。
eyeApps LLC

4
在Swift中经常出现的一个小问题是,(荒谬地)没有抽象函数,因此您只需“打印出您忘记了这个函数!” ... stackoverflow.com/a/24111430/294884
Fattie

@法蒂 您可以在函数上使用“ required”关键字来指定它需要子类实现。因此,实际上,它更像是轻微的无知而不是实际。
Dirk Bester

@DirkBester-干杯-等待,您正在与初始值设定项进行讨论?
Fattie

再次@DirkBester我可能有些困惑,但是您不能required在协议中的某个功能之前使用它,您只会得到'required' may only be used on 'init' declarations...
Fattie
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.