覆盖 Swift 协议扩展 [英] Swift Protocol Extensions overriding

查看:30
本文介绍了覆盖 Swift 协议扩展的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在试验 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!!

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:

...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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆