代码之家  ›  专栏  ›  技术社区  ›  J. Doe

协议中的公共默认初始化

  •  0
  • J. Doe  · 技术社区  · 6 年前

    我有这个密码:

    public protocol MyProtocol {
        init()
    }
    
    public extension MyProtocol {
        public init() {
            self.init()
        }
    }
    
    public final class MyClass: MyProtocol {}
    

    我有个错误说:

    初始值设定项“init()”必须声明为public,因为它与 公共协议“MyProtocol”中的要求

    如果我移除访问控制( public )以前 final ,它起作用了。但为什么呢?有没有办法让协议处理init?我以为所有的协议成员都是含蓄的 公众的 默认情况下。

    更奇怪的是 init 只有在 extension 公众的 默认情况下:

    public protocol MyProtocol {
        init()
    }
    
    public extension MyProtocol {
        public init() {
            self.init()
        }
    
        public init(youDoNotHaveToImplementMe: Any) {
            self.init()
        }
    }
    
    public final class MyClass: MyProtocol {
        public init() {}
    }
    

    如您所见,新的init实际上是 公众的 . 我期望我的正常 初始 应该是 公众的 也。为什么不是这样?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Fabian    6 年前

    MyClass 应该符合给定的协议 MyProtocol ,即使 类名 是公开的。但是怎么会 类名 符合 我的协议 ,如果 类名 是公共的,但它的init在另一个模块中不可见?它将符合 我的协议 (签名是这样说的)同时也不是(没有可见的init)。

    因为您的协议不能确定覆盖使用它的类的所有成员,所以您在协议中声明的任何初始值设定项都需要将类的“未知”成员的初始化委托给类本身提供的另一个初始值设定项。

    Source

    自从 类名 默认初始值设定项是内部的如果在 类名 是公开的。