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

协议扩展初始化器

宋铭
2023-03-14
问题内容

我想知道在一个仅包含初始化功能并且仅打算在具体类中进行扩展的简单类中,对于等效于该初始值设定项的协议等效于什么。

因此,最简单的方法可能就是显示代码-我正在寻找与以下内容等效的协议扩展:

import UIKit

class Thing {
    var color:UIColor
    init(color:UIColor) {
        self.color = color
    }
}
class NamedThing:Thing {
    var name:String
    init(name:String,color:UIColor) {
        self.name = name
        super.init(color:color)
    }
}
var namedThing = NamedThing(name: "thing", color: UIColor.blueColor())

我期望代码看起来像这样:

protocol Thing {
    var color:UIColor {get set}
}
extension Thing {
    init(color:UIColor) {
        self.color = color
    }
}
class NamedThing:Thing {
    var name:String
    var color:UIColor
    init(name:String,color:UIColor) {
        self.name = name
        self.init(color:color)
    }
}

我已经看到其他StackOverflow问题中建议的解决方案,但是我不确定它们是否有效,也不确定在类初始化程序中专门解决此问题。


问题答案:

您必须提供一个有效的初始化链来创建类的实例,并且这限制了协议中初始化程序的选择。

由于不能确定协议是否涵盖使用该协议的类的所有成员,因此您在协议中声明的任何初始化器都需要将类的“未知”成员的初始化委托给该类本身提供的另一个初始化器。

我调整了您的示例,以使用基本的init()作为协议的委托初始化程序来说明这一点。

如您所见,这要求您的类在调用init()时为所有成员实现初始值。在这种情况下,我通过在每个成员的声明中提供默认值来做到这一点。而且,由于某些成员并不总是有实际的初始值,因此我将其更改为自动展开可选对象。

为了使思考更有趣,您的类不能将初始化委派给协议提供的初始化程序,除非它是通过便捷初始化程序进行的。

我想知道所有这些限制是否值得解决。我怀疑您正在尝试使用协议,因为您需要在实现该协议的类之间一致地初始化一堆公共变量。也许使用委托类将提供比协议少花时间的解决方案(只是一个想法)。

protocol Thing:AnyObject
{
    var color:UIColor! { get set }
    init()
}

extension Thing 
{    
    init(color:UIColor)
    {  
       self.init()
       self.color = color
    }
}

class NamedThing:Thing 
{
    var name:String!   = nil
    var color:UIColor! = nil

    required init() {}

    convenience init(name:String,color:UIColor) 
    {
        self.init(color:color)
        self.name = name
    }
}


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

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

  • 问题内容: 我正在尝试使用Swift协议扩展,却发现这种行为令人困惑。您能帮我得到我想要的结果吗? 请参阅代码最后4行的注释。(如果需要,可以将其复制粘贴到Xcode7游乐场)。谢谢!! 问题答案: 简短的答案是协议扩展不执行类多态性。这是有一定道理的,因为协议可以被结构或枚举采用,并且因为我们不希望仅在没有必要的地方采用协议来引入动态调度。 因此,在中,实例变量(可能更准确地写为)并不意味着您认

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

  • 问题内容: 我正在使用swift 2.0,我有一个协议和对该协议的扩展来创建方法的默认实现,代码如下: 稍后,我在代码中尝试调用此方法,并收到一条错误消息: “不能在不可变值上使用变异成员:’自身’是不可变的” 代码如下: 我唯一想到的是这种情况下的“ Self”是协议,而不是类。但是,我必须缺少一些东西才能使该概念起作用。该协议定义的方法的默认实现,该方法还可以编辑同一协议定义的值。 谢谢您的帮

  • 据我所知,协议缓冲区主要用于控制服务器和客户端代码的项目。我的一般问题是——协议缓冲区能否用于将二进制消息序列化/反序列化到使用现有协议的服务器?所以,我的问题: > 如果协议缓冲区不支持本机微调现有协议的序列化/反序列化方式,那么可以通过扩展添加该功能吗?是否可以以某种方式添加序列化/反序列化方法可以识别的关键字?也许这可以通过扩展或修改protobuf csharp port或protobuf