在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ 访问控制限制从其他源文件和模块中的代码访问部分代码。使用此功能,您可以隐藏代码的实现细节,并指定可以访问和使用该代码的首选接口。 您可以为单个类型(类,结构和枚举)以及属于这些类型的属性,方法,初始化程序和下标分配特定的访问级别。协议可以限制在特定的上下文中,全局常量,变量和函数也可以。 除了提供各种级别的访问控制之外,Swift通过为典型方案提供默认访问级别来减少指定显式访问控制级别的需要。确实,如果您正在编写一个单一目标的应用程序,则可能根本不需要指定显式的访问控制级别。 笔记 为了简洁起见,可以在其上应用访问控制的代码的各个方面(属性,类型,函数等)在以下各节中称为“实体”。 模块和源文件Swift的访问控制模型基于模块和源文件的概念。 甲模块是代码分布框架或应用程序的内置和运输为单个单元,并可以通过与Swift的另一个模块引入的单个单元 Xcode中的每个构建目标(例如应用程序捆绑包或框架)在Swift中都被视为一个单独的模块。如果您将应用程序代码的各个方面归为一个独立的框架(可能是在多个应用程序之间封装和重用该代码),那么当在应用程序中导入和使用该框架时,您在该框架中定义的所有内容都将成为单独模块的一部分,或在其他框架中使用它时。 甲源文件是一个模块内的单个夫特源代码文件(实际上,一个应用程序或框架内的一个单独的文件)。尽管通常在单独的源文件中定义单个类型,但是单个源文件可以包含多个类型,函数等的定义。 访问级别Swift为您代码中的实体提供了五种不同的访问级别。这些访问级别与定义实体的源文件有关,也与源文件所属的模块有关。
开放访问是最高(最低限制)访问级别,私有访问是最低(最高限制)访问级别。 开放访问仅适用于类和类成员,并且与公共访问不同,它允许模块外部的代码进行子类化和覆盖,这在下面的Subclassing中进行了讨论。明确地将一个类标记为打开表明您已经考虑了使用该类作为超类的其他模块的代码的影响,并且已相应地设计了该类的代码。 访问级别指导原则Swift中的访问级别遵循总体指导原则:不能用具有较低(更严格)访问级别的另一个实体来定义实体。 例如:
下面将详细介绍该指导原则对语言的不同方面的具体含义。 默认访问级别如果您自己未指定显式访问级别,则代码中的所有实体(有一些特定的例外,如本章稍后所述)都具有默认的内部访问级别。因此,在许多情况下,您无需在代码中指定显式的访问级别。 单目标应用程序的访问级别当您编写简单的单目标应用程序时,应用程序中的代码通常是独立包含在应用程序内的,不需要在应用程序模块之外使用。内部的默认访问级别已经符合此要求。因此,您无需指定自定义访问级别。但是,您可能希望将代码的某些部分标记为私有文件或私有文件,以便在应用程序模块内的其他代码中隐藏其实现细节。 框架的访问级别开发框架时,请将该框架的面向公众的接口标记为开放或公共,以便其他模块(例如导入该框架的应用程序)可以查看和访问它。此面向公众的接口是框架的应用程序编程接口(或API)。 笔记 框架的任何内部实现细节仍可以使用内部的默认访问级别,或者如果您想将它们从框架内部代码的其他部分隐藏起来,则可以将其标记为私有或文件私有。仅当您希望实体成为框架API的一部分时,才需要将其标记为开放或公共。 单元测试目标的访问级别当您编写具有单元测试目标的应用程序时,需要使该应用程序中的代码可用于该模块才能进行测试。默认情况下,其他模块只能访问标记为开放或公开的实体。但是,如果您使用 访问控制语法通过将一个定义实体的访问级别
除非另有说明,否则默认访问级别是内部的,如默认访问级别中所述。这意味着
自订类型如果要为自定义类型指定显式访问级别,请在定义类型时执行此操作。然后,只要访问级别允许,就可以使用新类型。例如,如果定义了文件专用类,则该类只能在定义了文件专用类的源文件中用作属性的类型,或用作函数参数或返回类型。 类型的访问控制级别也会影响该类型的成员(属性,方法,初始化程序和下标)的默认访问级别。如果将类型的访问级别定义为私有或文件私有,则其成员的默认访问级别也将为私有或文件私有。如果将类型的访问级别定义为内部或公共(或使用默认的内部访问级别而不显式指定访问级别),则类型成员的默认访问级别将是内部的。 重要的 公用类型默认情况下具有内部成员,而不是公用成员。如果要让类型成员公开,则必须明确地将其标记为公共成员。此要求确保您选择发布类型的面向公众的API,并避免错误地将类型的内部工作方式呈现为公共API。
元组类型元组类型的访问级别是该元组中使用的所有类型中限制性最强的访问级别。例如,如果您由两种不同的类型组成一个元组,一种具有内部访问权限,另一种具有私有访问权限,则该复合元组类型的访问级别将是私有的。 笔记 元组类型没有类,结构,枚举和函数那样的独立定义。元组类型的访问级别是根据构成元组类型的类型自动确定的,因此无法明确指定。 功能类型函数类型的访问级别被计算为函数的参数类型和返回类型中限制性最强的访问级别。如果函数的计算访问级别与上下文默认值不匹配,则必须明确指定访问级别作为函数定义的一部分。 下面的示例定义了一个名为的全局函数
该函数的返回类型是一个元组类型,由上面在Custom Types中定义的两个自定义类组成。这些类中的一个被定义为内部类,另一个被定义为私有类。因此,复合元组类型的总体访问级别是私有的(元组组成类型的最小访问级别)。 由于函数的返回类型是私有的,因此必须使用
枚举类型枚举的个别情况将自动获得与其所属的枚举相同的访问级别。您不能为单个枚举案例指定其他访问级别。 在下面的示例中,
原始值和关联值枚举定义中用于任何原始值或关联值的类型的访问级别必须至少与枚举的访问级别一样高。例如,您不能将私有类型用作具有内部访问级别的枚举的原始值类型。 嵌套类型嵌套类型的访问级别与其包含类型相同,除非包含类型是公共的。在公共类型内定义的嵌套类型具有内部的自动访问级别。如果希望公共类型中的嵌套类型可公开使用,则必须将嵌套类型显式声明为public。 子类化您可以将可在当前访问上下文中访问的任何类作为其子类,并且在与该子类相同的模块中对其进行定义。您还可以将在不同模块中定义的任何开放类作为子类。子类不能具有比其父类更高的访问级别-例如,您不能编写内部父类的公共子类。 此外,对于在同一模块中定义的类,您可以覆盖在特定访问上下文中可见的任何类成员(方法,属性,初始化程序或下标)。对于在另一个模块中定义的类,您可以覆盖任何打开的类成员。 覆盖可以使继承的类成员比其超类版本更易于访问。在下面的示例中,class
子类成员调用访问权限比子类成员低的超类成员甚至是有效的,只要对超类成员的调用发生在允许的访问级别上下文内(即,与文件私有成员调用的父类的超类,或内部成员调用的父类的父类在同一个模块中):
由于超类 常量,变量,属性和下标常量,变量或属性不能比其类型更公开。例如,用私有类型编写公共属性是无效的。同样,下标不能比其索引类型或返回类型更公开。 如果常量,变量,属性或下标使用私有类型,则常量,变量,属性或下标也必须标记为
吸气剂和二传手常量,变量,属性和下标的获取器和设置器将自动获得与其所属的常量,变量,属性或下标相同的访问级别。 您可以为setter提供比其相应的getter更低的访问级别,以限制该变量,属性或下标的读写范围。您可以指定由写作较低访问级别 笔记 此规则适用于存储的属性以及计算的属性。即使您没有为存储的属性编写显式的getter和setter,Swift仍然会为您合成隐式的getter和setter以提供对存储属性的后备存储的访问。使用 下面的示例定义了一个名为的结构
该 在 如果创建
尽管可以 请注意,如果需要,您可以为getter和setter分配显式的访问级别。下面的示例显示了该
初始化器可以为自定义初始化程序分配访问级别,该访问级别应小于或等于其初始化的类型。唯一的例外是必需的初始化程序(如必需的初始化程序中所定义)。所需的初始化程序必须与其所属的类具有相同的访问级别。 与函数和方法参数一样,初始化程序的参数类型不能比初始化程序自己的访问级别更私有。 默认初始化器如Default Initializers中所述,Swift自动为所有结构或基类提供默认的初始化程序,而没有任何参数,而该结构或基类为其所有属性提供默认值,并且本身不提供至少一个初始化程序。 默认初始化程序具有与其初始化类型相同的访问级别,除非该类型定义为 结构类型的默认成员级初始化程序如果结构的任何存储属性都是私有的,则该结构类型的默认成员初始化器被视为私有的。同样,如果结构的任何存储属性是文件专用的,则初始化程序是文件专用的。否则,初始化程序的访问级别为internal。 与上面的默认初始值设定项一样,如果您希望在另一个模块中使用某个成员结构初始值设定项来初始化一个公共结构类型,则您必须自己提供一个公共成员成员初始值设定项作为类型定义的一部分。 通讯协定如果要为协议类型分配显式访问级别,请在定义协议时进行。这使您可以创建只能在特定访问上下文中采用的协议。 协议定义内每个需求的访问级别将自动设置为与协议相同的访问级别。您不能将协议要求设置为与其支持的协议不同的访问级别。这样可以确保所有协议要求在采用该协议的任何类型上都是可见的。 笔记 如果定义公共协议,则协议的要求在实施时就需要这些要求的公共访问级别。此行为不同于其他类型,在其他类型中,公共类型定义表示该类型成员的内部访问级别。 协议继承如果定义从现有协议继承的新协议,则新协议最多可以具有与其继承的协议相同的访问级别。例如,您不能编写从内部协议继承的公共协议。 协议一致性一种类型可以符合一种协议,该协议具有比该类型本身更低的访问级别。例如,您可以定义可以在其他模块中使用的公共类型,但是其与内部协议的一致性只能在内部协议的定义模块中使用。 类型符合特定协议的上下文是该类型的访问级别和协议的访问级别中的最小值。例如,如果一个类型是公共的,但是它遵循的协议是内部的,则该类型对该协议的遵从性也是内部的。 当编写或扩展类型以符合协议时,必须确保每种协议要求的类型实现至少具有与该协议所遵循的类型相同的访问级别。例如,如果公共类型符合内部协议,则每个协议要求的类型实现必须至少是内部的。 笔记 在Swift中,就像在Objective-C中一样,协议一致性是全局的-类型不可能在同一程序内以两种不同方式符合协议。 扩展名您可以在类,结构或枚举可用的任何访问上下文中扩展类,结构或枚举。在扩展中添加的任何类型成员都具有与在要扩展的原始类型中声明的类型成员相同的默认访问级别。如果扩展公共或内部类型,则添加的任何新类型成员的默认访问级别为内部。如果扩展文件专用类型,则您添加的任何新类型成员都具有文件专用的默认访问级别。如果扩展私有类型,则添加的任何新类型成员的默认访问级别均为私有。 另外,您可以使用明确的访问级别修饰符(例如 如果您使用扩展名添加协议一致性,则不能为该扩展名提供明确的访问级别修饰符。相反,协议本身的访问级别用于为扩展内的每个协议要求实现提供默认访问级别。 扩展中的私人成员与扩展类,结构或枚举位于同一文件中的扩展的行为就像扩展中的代码已作为原始类型的声明的一部分编写一样。因此,您可以:
此行为意味着您可以以相同的方式使用扩展来组织代码,而不管您的类型是否具有私有实体。例如,给出以下简单协议:
您可以使用扩展来添加协议一致性,如下所示:
泛型通用类型或通用函数的访问级别是通用类型或函数本身的访问级别以及对其类型参数的任何类型约束的访问级别的最小值。 类型别名出于访问控制的目的,您定义的任何类型别名都将被视为不同的类型。类型别名的访问级别可以小于或等于其别名的访问级别。例如,私有类型别名可以为私有,文件私有,内部,公共或开放类型别名,但是公共类型别名不能为内部,文件私有或私有类型别名。 笔记 此规则也适用于用于满足协议一致性的关联类型的类型别名。
|
请发表评论