在Swift中何时使用协议
我今天问了一个问题,因为我今天有点迷路了。它是关于Swift和协议的,更多的是关于面向协议的编程(POP) 我读过关于它的文章,甚至是一本书,但我仍然感到困惑。每个人似乎都说协议是一个伟大的工具等等,但我并不真正理解它的力量 我有一个问题,因为我正在编写一个类卷,它是卷作为对象的表示。比方说在Swift中何时使用协议,swift,cocoa,swift-protocols,Swift,Cocoa,Swift Protocols,我今天问了一个问题,因为我今天有点迷路了。它是关于Swift和协议的,更多的是关于面向协议的编程(POP) 我读过关于它的文章,甚至是一本书,但我仍然感到困惑。每个人似乎都说协议是一个伟大的工具等等,但我并不真正理解它的力量 我有一个问题,因为我正在编写一个类卷,它是卷作为对象的表示。比方说 struct Volume { var value: Float = 1 var isLogScale: Bool = false var maxLogVolume: Float = 6.0 /
struct Volume {
var value: Float = 1
var isLogScale: Bool = false
var maxLogVolume: Float = 6.0 // value in dB
var maxLinearVolume: Float = 1.0
let dynamicRange: Float = 50.0
func convertLinearToLog() -> Float {
// Do some maths
}
func otherFunction() {
print("Hello, I'm the most useless function in the world.")
}
}
这是一门典型的课,没什么特别的
但是…我应该给我们一个这样的协议吗:
protocol VolumeProtocol {
var value: Float {get set}
var isLogScale: Bool {get set}
var maxLogVolume: Float {get set}
var maxLinearVolume: Float {get set}
let dynamicRange: Float {get}
func convertLinearToLog() -> Float
func otherFunction()
}
然后像这样重新实现一切
struct MyVolumeClass: VolumeProtocol {
// Same thing as before
}
我真的无法回答这个问题,所以如果您能帮助我何时使用协议,何时不使用协议,我将不胜感激。协议有多个用例,但请这样想:
- 对于类,协议提供了与类层次结构分离的轻量级继承层次结构。给定一个类动物及其子类猫、狗、鸟和昆虫,如何指定只有鸟和昆虫共享
方法fly
- 对于结构,协议提供了一个继承层次结构,否则它将完全丢失!结构没有上层结构。那么,给定一只结构鸟和一只结构昆虫,您如何指定它们共享
方法fly
fly
方法,这就是故事的结尾。但是,当您需要谈论集合“所有具有fly
方法的类型”时,这就行不通了。当你希望编译器能够将fly
方法发送到一个对象,因为它有一个fly
方法时,你确实需要提到这个集合
解决方案是一个协议:
protocol Flier {
func fly()
}
现在传单是一种类型。符合Flier的任何类型的实例都可以在需要Flier的地方使用,编译器将允许您告诉任何Flier飞fly
,因此问题得到解决:
var myFlier : Flier = Bird() // if Bird conforms to Flier
myFlier.fly() // legal
您应该使用结构而不是类。顺便说一句,值得一看@LeoDabus你完全正确。抱歉,我在这里对类/结构犯了一个错误。事实上,这个案例完全是一个结构。我编辑了我的问题。感谢您的链接,使用协议的一个可能场景是,当您想抽象出几个类的一些常用方法/属性,但您不想出于任何原因使用继承(例如您的类已经需要从另一个类继承)。对于您当前的实现,创建
VolumeProtocol
是没有意义的,因为我不认为您会有几个不同的类符合此协议。@DávidPászor感谢您的解释,这就是为什么我觉得我的案例不好的原因。事实上,协议可以被看作是一个大的超类,我们把它分割成一个小的超类。事实上,在我的例子中,它可能是符合先前协议的procotolsvolume
、audioFormat
和classsingleAudioPlayer
multipleAudioPlayer
。对我来说,这样做还是不自然的,因为编写带有声明的“协议”对我来说仍然是无用的(我只对委托模式使用了协议),但它有助于维护code@DEADBEEF您还可以在协议中定义函数的默认实现,这样协议就不仅仅是一个声明