当前位置: 首页 > 知识库问答 >
问题:

所需初始化的访问控制

巫马曜文
2023-03-14

必需的初始值设定项的访问控制规则似乎与未指定必需的规则不同。为什么?

public class A {
  // required init() must be public, why?
  public required init() { }
}

public class B {
  // init() does not need to be public, why?
  init() { }
}

共有1个答案

柴彬
2023-03-14

首先,让我们把规则搞清楚。不需要将必需的初始化器标记为Public。它只要求必需的初始化器与类一样可访问。如果你的类是Public,它的初始化器也必须是Public。如果你的类是内部,它需要的初始化器也必须是内部(从技术上讲,你可以使它公共,但这没有意义,并生成一个警告)。当然,如果你的类是私有的,所需的初始化器也应该是私有的

这里有两个原因,但它们需要了解required关键字实际在做什么。

首先,必需的关键字保证这个类及其所有子类实现这个特定的初始化器。需要初始化器的主要原因之一是协议一致性,最流行的例子是NSCoding,它需要init(coder:)初始化器。考虑到这一点,让我们考虑一个试图实现该协议的类:

public class MySwiftClass: NSObject, NSCoding {
    // some implementations
    // including the two requirements of the NSCoding protocol
}

现在,试着尝试使用这个:

let mySwiftObject = MySwiftClass(coder: aCoder)

我们应该可以毫无问题地做到这一点,对吗?我的意思是,毕竟,myswitclass符合NSCoding协议,并且NSCoding协议保证会有一个init(coder:)初始值设定项。

但是如果您被允许将init(coder:)标记为比类更低的访问级别,则会有一个范围,在该范围内可以看到类,但无法访问其所需的初始化器...所以尽管知道这一点类符合具有所需初始化器的协议,或者从具有所需初始化器的父类继承,我们将无法调用所需的初始化器,因为对于我们所处的范围,它似乎不存在。

第二个原因是子类化本身。

让我们以父类为例:

public class ParentClass {
    required init() {}
}

我们希望需要零参数初始化器。这意味着,如果有任何东西继承自家长类,它还必须确保实现了零参数初始化器。但是,如果允许我们让所需的初始化器具有比类本身更小的范围,那么就有一个范围,在这个范围内我们可以看到类,但是我们看不到所需的初始化器,那么在这个范围内创建的子类如何管理甚至知道他们必须实现所需的初始化器吗?

 类似资料:
  • 我试图为Dropwizard创建一个调度作业,该作业每分钟运行一次,并查询数据库中的值。 为此,我需要在< code>initialize()阶段注册一些Dao和一个服务,如下所示: JDBI需要Dropw的和配置对象。 是否可以在这个阶段访问这些,以便正确设置我的依赖项?

  • 问题内容: 我在我的应用程序中使用ArrayList。 我想知道从Singleton类初始化ArrayList的确切过程。 该数据将在其他一些活动中使用。 有人可以帮助了解Singleton课堂吗? 问题答案: 这是创建单例类的方法: 任何需要调用arrayList的地方都可以: 要将元素添加到数组,请使用: 要么

  • 在 Swift 3 中,dispatch_once函数被删除,迁移指南建议使用初始化闭包: 让myGlobal = { … global包含对闭包调用的初始化…}() _ = myGlobal //使用myGlobal只会在首次使用时调用初始化代码。 我想从初始化闭包中访问“Self”实例变量,如下所示: 为什么“自我”在闭包中是不可接近的,如何才能使它成为现实?

  • 在“线性回归的简洁实现”一节中,我们通过init模块来初始化模型的全部参数。我们也介绍了访问模型参数的简单方法。本节将深入讲解如何访问和初始化模型参数,以及如何在多个层之间共享同一份模型参数。 我们先定义一个与上一节中相同的含单隐藏层的多层感知机。我们依然使用默认方式初始化它的参数,并做一次前向计算。与之前不同的是,在这里我们从MXNet中导入了init模块,它包含了多种模型初始化方法。 from

  • 问题内容: 我想延迟控制器的初始化,直到从服务器收到必要的数据为止。 我找到了针对Angular1.0.1的解决方案:延迟AngularJS路由更改,直到加载模型以防止闪烁,但无法使其与Angular1.1.0一起使用 模板 ​ JavaScript http://jsfiddle.net/dTJ9N/1/ 问题答案: 由于$ http返回了promise,因此创建自己的deferred仅在htt

  • 问题内容: 如果您有一个控制器来操作Angular.js中的$ scope变量,是否有惯用的方法: 重置控制器的$ scope,然后 重新启动控制器初始化? 对于复杂的控制器,不必将每个变量都重置为其初始值将非常方便,特别是如果您真正想要的是对控制器和范围进行简单的重新初始化。通过再次导航到相同的URL 并没有帮助。 编辑:假设我不能使用任何黑客工具,因为这会违反Chrome打包应用中的CSP。