我读过有关它的文章,甚至是一本书,但我仍然感到困惑。每个人似乎都说协议是一个很好的工具等等,但我真的不了解它的力量。
我有一个问题,因为我正在编写一个类Volume,它是一个卷作为对象的表示。我们说
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
}
我真的无法回答这个问题,所以如果你能帮助我什么时候使用协议,什么时候我不会欣赏。
答案 0 :(得分:6)
协议有多个用例,但请这样考虑:
对于类,协议提供了与类层次结构分离的轻量级继承层次结构。给定一个Animal类及其子类Cat,Dog,Bird和Insect,您如何指定只有Bird和Insect共享fly
方法?
对于结构体,协议提供了一个继承层次结构,否则它将完全丢失!结构没有上层结构。那么,给定struct Bird和struct Insect,您如何指定它们共享fly
方法?
现在,您可以回答Bird和Insect碰巧有fly
种方法,这就是故事的结尾。但是当你需要谈论所有具有fly
方法&#34;的类型时,这不会做。如果希望编译器能够将<{1}}方法发送到对象,并且 a ,那么做需要说明该集合fly
方法。
解决方案是一个协议:
fly
现在Flier是一个类型。符合Flier的任何类型的实例都可以在需要Flier的地方使用,编译器会让你告诉任何Flier protocol Flier {
func fly()
}
,所以问题就解决了:
fly