swift2 Swift中的协议导向编程是什么?它带来了什么附加值?

3pmvbmvn  于 2022-11-06  发布在  Swift
关注(0)|答案(7)|浏览(181)

来自Apple自己的网站:“Swift设计的核心是两个非常强大的想法:面向协议的编程和第一类值语义”。
有人能详细说明什么是面向协议的编程,它带来了什么附加值吗?
我读过this,也看过Swift video中的面向协议编程,但是来自Objective-C背景的我仍然不理解它。我恳请你用一个 * 非常 * 简单的英语回答沿着代码片段和技术细节,说明它与Objective-C有何不同。
我的困惑之一是使用<tableViewDelegate, CustomDelegate>,难道我们不能在Objective-C中也遵守多个协议吗?那么,Swift又是怎么回事?
编辑:请看Protocol-Oriented Views视频。我发现这个视频更基本,更容易掌握一个有意义的用例。WWDC视频本身有点高级,需要更多的广度。此外,这里的答案有些抽象。

j7dteeu8

j7dteeu81#

前言:POP和OOP并不是相互排斥的,它们是密切相关的设计范式。
POP优于OOP的主要方面是它更喜欢composition over inheritance。这有几个好处。
在大型继承层次结构中,祖先类 * 倾向于 * 包含大多数(广义)功能,叶子子类只做了最小的贡献。这里的问题是祖先类最终做了很多事情。例如,Car驱动器,存储货物,座位乘客,播放音乐,等等。这些是许多功能,每一个都非常不同,但是它们都被不可分割地集中到Car类中。Car的后代,如FerrariToyotaBMW等,都对这个基类进行最小的修改。
这样做的结果是减少了代码重用。我的BoomBox也播放音乐,但它不是汽车。从Car继承音乐播放功能是不可能的。
Swift鼓励的是将这些大的整体类分解成更小的组件,这样就可以更容易地重用这些组件,CarBoomBox都可以使用MusicPlayer
Swift提供了多种特性来实现这一点,但到目前为止最重要的是协议扩展。它们允许协议的实现独立于其实现类,因此许多类可以简单地实现该协议并立即获得其功能。

yvfmudvl

yvfmudvl2#

令我惊讶的是,没有一个答案提到POP中的值类型。

为了理解什么是面向协议的编程,您需要理解面向对象编程的缺点。
1.它(Objc)只有一个继承。如果我们有非常复杂的继承层次结构,底层类可能会有很多不必要的状态要保存。
1.它使用的类是引用类型。引用类型可能导致代码不安全。例如,在修改引用类型的集合时处理这些集合。
而在面向协议的swift编程中:
1.它可以符合多种协议。
1.它不仅可以用于类,还可以用于结构枚举
1.它具有协议扩展,为符合协议的所有类型提供了通用功能
1.它倾向于使用值类型而不是引用类型。看一下标准的swift库here,你会发现大多数类型都是结构,也就是值类型。但这并不意味着你根本不用class,在某些情况下,你必须使用class。
因此,面向协议的编程只不过是试图解决OOP缺点的另一种编程范式。

qyyhg6bp

qyyhg6bp3#

在Objective C中,协议与大多数语言中的接口是一样的,因此在Objective C中,协议的使用仅限于SOLID原则“* 依赖于抽象。不依赖于具体 *”。
在Swift中,协议得到了很大的改进,因为它们仍然可以用作接口,事实上它们更接近于类(如C++中的Abstract classes
在Objective C中,类之间共享功能的唯一方式是继承。你可以继承唯一的一个父类。在Swift中,你也可以采用你想要的任意多的协议。由于Swift中的协议可以有默认的方法实现,它们给予了我们一个全功能的Multiple inheritance。更大的灵活性,更好的代码重用--太棒了!

结论:
面向协议的编程OOP基本相同,但它对功能共享给予了额外关注,不仅通过继承,还通过协议采用(Composition over inheritance)。

值得一提的是,在C中,抽象类与Swift中的协议非常相似,但没有人说C支持某种特定类型的OOP。因此,如果我们谈论编程范例,* 一般 * POP是OOP的一个版本。对于Swift来说,POP是OOP的一个改进版本。

mrzz3bfm

mrzz3bfm4#

补充上述答案

协议是一个接口,其中声明了方法和属性的签名,并且枚举的任何类/结构/枚举子类都必须遵守协定,这意味着它们必须实现超类协议中声明的所有方法和属性。
使用协议的原因

类提供单一继承,而结构不支持继承,因此引入了协议。

扩展在协议中声明的方法可以在扩展中实现,以避免在协议被继承到多个具有相同方法实现的类/结构体中时代码的冗余。我们可以通过简单地声明结构体/枚举的对象来调用方法。甚至我们可以将扩展限制为一系列类,只有受限制的类能够使用扩展内部实现的方法,而其余的类必须在自己的类内部实现方法。
示例

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中,假设我们有一个由飞机、自行车、汽车等继承的车辆基类。在这里,break、acceleration可能是三个子类中的公共方法,但不是飞机的可飞行方法。因此,如果我们也在OOP中声明可飞行方法,bike和car子类也有inheriteflyable方法,该方法对这些类没有用处。因此,在POP中,我们可以声明两个协议,一个是用于可飞行物体的,另一个是用于中断和加速方法的,并且可飞行协议可以被限制为仅由飞机使用

nwnhqdif

nwnhqdif5#

面向协议的编程(POP)

协议优先方法

  • 协议是面向对象程序设计概念的核心。抽象、继承、多态、封装。
  • 作为SOLID About(https://stackoverflow.com/a/66087638/4770877)基础的协议
  • 协议代替类层次树,难以支持类继承,而且对性能有一定影响
  • 类/结构可以实现多个协议(一种多重继承)
  • 合成优先于继承。
extension MyClass: MyProtocol {
}
  • 默认方法。所有实现者共享的实现
extension MyProtocol {
    func foo() {
        //logic
    }
}
  • 协议继承。一个协议可以扩展另一个协议。第一个协议的实现者应该实现第一个和第二个协议的所有内容
protocol ProtocolB: ProtocolA {
}
  • 实值型别实作通信协定(如一般指涉型别)About(https://stackoverflow.com/a/59219141/4770877)
cbjzeqam

cbjzeqam6#

面向协议的编程(POP)

  • 从Swift 2.0开始
  • 类(OOP)
  • 是指涉型别
  • 内存泄漏、存储的数据不正确、在复杂的多线程环境中访问的竞争条件
  • 可以通过在链时间继承超类的成员来增大
  • 结构(POP)
  • 是值类型-每次需要时创建新副本
  • 提供多继承-继承协议
  • 通信协定:
  • 定义需要哪些方法、属性和初始化o可以继承其他协议
  • 不必使用override关键字来实现协议功能
  • 扩展名:
  • 协议的默认值和默认实现
  • 可以向协议添加额外的成员
bwitn5fc

bwitn5fc7#

什么是面向协议的编程?2什么是POP?

  • 是一种新的编程范式
  • 我们从定义协议开始设计我们的系统。2我们依靠新的概念:协议扩展、协议继承和协议组合。
  • 值类型可以从协议继承,甚至可以从多个协议继承。因此,有了POP,值类型已经成为Swift中的头等公民。值类型如枚举、结构 *POP允许您使用支持多个实现的协议向类或结构或枚举添加功能。
  • 苹果告诉我们:“不要从类开始,从协议开始。”为什么?协议作为比类更好的抽象。
    通信协定:是Swift的一个基本特性。它们在Swift标准库的结构中起着主导作用,是一种常见的抽象方法。协议用于定义“方法、属性和其他适合特定任务或功能的需求的蓝图”。

面向协议编程的优点:

  • 所有类都是相互分离的
  • 将申报与执行的关切分开
  • 可重复使用性
  • 可测试性

相关问题