当前位置: 首页 > 面试题库 >

Swift协议扩展覆盖

贺宜修
2023-03-14
问题内容

我正在尝试使用Swift协议扩展,却发现这种行为令人困惑。您能帮我得到我想要的结果吗?

请参阅代码最后4行的注释。(如果需要,可以将其复制粘贴到Xcode7游乐场)。谢谢!!

//: 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"

问题答案:

简短的答案是协议扩展不执行类多态性。这是有一定道理的,因为协议可以被结构或枚举采用,并且因为我们不希望仅在没有必要的地方采用协议来引入动态调度。

因此,在中getColor()color实例变量(可能更准确地写为self.color)并不意味着您认为它会做什么,因为您正在以类多态的方式思考,而协议不是。所以这有效:

let colorB = B().color // is "Red color" - OK

…因为您要让 班级 解决问题color,但这并不能满足您的期望:

let b = B().getColor() // is "Default color" BUT I want it to be "Red color"

…因为该getColor方法完全在协议扩展中定义。您可以通过getColor在B中重新定义来解决此问题:

class B: A, RedColor {
    func getColor() -> String {
        return self.color
    }
}

现在,该类的getColor被调用了,它对什么self是一个多态的想法。



 类似资料:
  • 扩展说明 RPC 协议扩展,封装远程调用细节。 契约: 当用户调用 refer() 所返回的 Invoker 对象的 invoke() 方法时,协议需相应执行同 URL 远端 export() 传入的 Invoker 对象的 invoke() 方法。 其中,refer() 返回的 Invoker 由协议实现,协议通常需要在此 Invoker 中发送远程请求,export() 传入的 Invoker

  • 协议和扩展 你可以扩展一个已经存在的类型来采纳和遵循一个新协议, 就算是你无法访问现有类型的源代码也行. 扩展可以添加新的属性、方法和下标到已经存在的类型, 并且因此允许你添加协议需要的任何需要. protocol TextRepresentable { var textualDescription: String { get } } // 此处并无Dice这个类, 以及其sides属性

  • 问题内容: 假设我有以下协议: 而且我有以下结构: 如您所见,我必须“遵循”结构A和结构B中的Identifiable协议。但是想象一下,如果我还有N个需要符合该协议的结构……我不想“复制/粘贴” ‘一致性(变量ID:整数,变量名称:字符串) 所以我创建了一个 协议扩展 : 现在,通过此扩展,我可以创建符合Identifiable协议的结构,而不必同时实现这两个属性: 现在的问题是我不能为id属性

  • 问题内容: 我正在尝试使用协议扩展在某些方法上添加默认行为,例如: 您可能会猜到,键盘永远不会消失。我真的看不出问题出在哪里。这是语言限制吗?有人已经成功做到了吗? 编辑: 正如@Logan所建议的,默认协议的方法实现不适用于标记为的协议。但是,具有以下签名 我已经测试了默认的实现,它似乎运行良好: 问题答案: 我不能100%积极,但是我相信这是正在发生的事情: 无法从访问协议扩展。由于是协议,因

  • 本文作为HPB知识库的一种扩展阅读, RLP编码是数据序列化的主要方法,本文介绍RLP编码的主要规则和原理分析,RLP编码具有较好的数据处理效率,尤其是将长度和类型统一作为前缀,实际上RLP是基于ASCII编码的一种结构化扩充,既能表示长度还能表示类型,是一种非常紧凑的结构化编码方案 RLP(Recursive Length Prefix,递归长度前缀)是一种编码算法,用于编码任意的嵌套结构的二进

  • 问题内容: 我想知道在一个仅包含初始化功能并且仅打算在具体类中进行扩展的简单类中,对于等效于该初始值设定项的协议等效于什么。 因此,最简单的方法可能就是显示代码-我正在寻找与以下内容等效的协议扩展: 我期望代码看起来像这样: 我已经看到其他StackOverflow问题中建议的解决方案,但是我不确定它们是否有效,也不确定在类初始化程序中专门解决此问题。 问题答案: 您必须提供一个有效的初始化链来创