Swift协议扩展覆盖 [英] Swift Protocol Extensions overriding
问题描述
我正在试验Swift协议扩展,发现这种行为令人困惑.您能帮我得到我想要的结果吗?
I'm experimenting with Swift protocol extensions and I found this quite confusing behaviour. Could you help me how to get the result I want?
请参阅代码最后4行的注释. (如果需要,可以将其复制粘贴到Xcode7游乐场).谢谢!!
See the comments on the last 4 lines of the code. (You can copy paste it to Xcode7 playground if you want). Thank you!!
//: Playground - noun: a place where people can play
import UIKit
protocol Color { }
extension Color { var color : String { return "Default color" } }
protocol RedColor: Color { }
extension RedColor { var color : String { return "Red color" } }
protocol PrintColor {
func getColor() -> String
}
extension PrintColor where Self: Color {
func getColor() -> String {
return color
}
}
class A: Color, PrintColor { }
class B: A, RedColor { }
let colorA = A().color // is "Default color" - OK
let colorB = B().color // is "Red color" - OK
let a = A().getColor() // is "Default color" - OK
let b = B().getColor() // is "Default color" BUT I want it to be "Red color"
推荐答案
简短的答案是协议扩展不执行类多态性.这是有一定道理的,因为协议可以被结构或枚举采用,并且因为我们不希望仅在没有必要的情况下仅采用协议来引入动态调度.
The short answer is that protocol extensions don't do class polymorphism. This makes a certain sense, because a protocol can be adopted by a struct or enum, and because we wouldn't want the mere adoption of a protocol to introduce dynamic dispatch where it isn't necessary.
因此,在getColor()
中,color
实例变量(可能更准确地写为self.color
)并不意味着您认为的那样,因为您正在以类多态的方式思考,而协议不是.这样就可以了:
Thus, in getColor()
, the color
instance variable (which may be more accurately written as self.color
) doesn't mean what you think it does, because you are thinking class-polymorphically and the protocol is not. So this works:
let colorB = B().color // is "Red color" - OK
...因为您正在请求 class 来解析color
,但这并没有达到您的期望:
...because you are asking a class to resolve color
, but this doesn't do what you expect:
let b = B().getColor() // is "Default color" BUT I want it to be "Red color"
...因为getColor
方法完全在协议扩展中定义.您可以通过在B中重新定义getColor
来解决此问题:
...because the getColor
method is defined entirely in a protocol extension. You can fix the problem by redefining getColor
in B:
class B: A, RedColor {
func getColor() -> String {
return self.color
}
}
现在,该类的getColor
被调用,并且它对self
是什么具有多态性.
Now the class's getColor
is called, and it has a polymorphic idea of what self
is.
这篇关于Swift协议扩展覆盖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!