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

查看:224
本文介绍了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!!

//: 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屋!

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