Swift中面向协议的编程

通讯协定

Swift协议基本上是类/结构/枚举的契约,用于实现一组特定的方法和属性。

  //协议示例 
协议TableCellProtocol {
func buttonTapped()
}

Swift会检查在编译时实现的类是否满足协议的要求。 因此,这使开发人员甚至可以在运行程序之前找出代码中是否存在任何问题或错误。 与类相比,协议还带来了更多的抽象。

什么是面向协议的编程?

POP是一种新的编程方法,可以使用协议修饰我们的类,结构或枚举。 Swift不支持多重继承,因此,当您想向类中添加多种功能时,就会弹出问题。 POP使您可以使用支持多种实现的协议向类,结构或枚举添加功能。

OOP与POP

类之间的抽象建模依赖于继承。 子类将具有其超类的能力。 子类可以覆盖该功能,并添加特定的功能。 在您需要另一个班级的另一项技能之前,OOP可以完美发挥作用。 Swift中没有多重继承。 但是协议是蓝图,而不是父级。 协议通过描述实现类型应实现的内容来对抽象进行建模。 这是OOP和POP之间的主要区别。 OOP的另外两个优点是:

  • 类型可以符合多个协议。 这带来了完美的灵活性。
  • 协议也可以由类,结构和枚举扩展和采用。

在下面,我将创建一个武器协议,而不是类。

您可以为var和函数创建蓝图。 在协议中创建var可以使您的类通过强制定义该变量来使该协议符合该协议。 在此示例中,我们强制开发人员在使用Weapon协议时将名称,canFire和canCut vars添加到武器

 协议武器{ 
var名称:字符串{get}
var canFire:Bool {get}
var canCut:布尔{get}
}

现在,考虑一下我们有两种武器: 易燃,可切割。 我们将通过武器协议使用这些功能来创建所需的武器。

 协议可燃{ 
var magazineSize:Int {get}
}协议可剪切{
var重量:双倍{get}
var steel:字符串{get}
}

我们创建了技能和我们的武器协议。 让我们使用所有这些来创建结构。

  struct LongSword:武器,可切割{ 
命名:字符串
令长度= 5.5
令体重= 7.2
让canFire = false
让canCut = true
}
//长剑是具有切割能力的武器。结构AK47:武器,可燃{
让名称=“ AK47”
让magazineSize = 30
让canFire = true
让canCut = false
}
// ak47也是一种能够发射子弹的武器。

如您在上面看到的,我们使用协议装饰了结构。 协议迫使我们遵守它们,并且我们增加了我们想要的能力。 但是上面发生了一个问题,该问题涉及在我们的自定义结构中保留canFire和canCut功能。 我们该怎么做才能解决这个问题? 答案是协议扩展 🙂

 扩展武器{ 
var canFire:Bool {return self is Fireable}
var canCut:布尔{返回self是Cuttable}
}

因此,现在我们可以从AK47,Longsword和武器协议中删除所有canFire和canCut变量。 使用“返回自我是可触发的”可避免我们设置另一个实例var,并使我们的协议可以通过协议扩展灵活使用。

并将它们添加到您的游乐场,以查看其工作原理:

  let longsword = LongSword(名称:“武士”) 
longsword.canCut // true
longsword.canFire //否
longsword.namelet ak47 = AK47()
ak47.canFire //是
ak47.canCut //否

扩展协议以支持Swift中的继承

  //我从Fireable扩展了Bombable协议。 使用这个新协议,//我可以在Firable中添加另一个功能maxDistance。 
协议可炸弹:可燃{
var maxDistance:Double {get}
} //然后我创建了全新的武器,原子
struct Atom:武器,可炸弹{
让名称=“原子”
让magazineSize = 1
令maxDistance = 1000
}
//因此,这种可扩展性使我的代码库更加灵活。 考虑一下,//我不希望在Fireable中使用maxDistance,但是在Bombable中。

现在,整个协议实现如下所示: