Swift Control de Acceso
El control de acceso puede limitar el nivel de acceso que el código en otros archivos fuente o módulos tiene sobre tu código.
Puedes establecer explícitamente un nivel de acceso para un tipo individual (clase, estructura, enumeración), y también puedes establecerlo para las propiedades, funciones, métodos de inicialización, tipos básicos, índices de subíndice, etc. de estos tipos.
Los protocolos también pueden estar restringidos a un cierto ámbito de uso, incluidas las constantes globales, variables y funciones dentro del protocolo.
El control de acceso se basa en módulos y archivos fuente.
Un módulo se refiere a un Framework o Application construido y publicado como una unidad independiente. En Swift, un módulo puede usar la palabra clave import para introducir otro módulo.
Un archivo fuente es un único archivo de código fuente, que normalmente pertenece a un módulo. El archivo fuente puede contener definiciones de múltiples clases y funciones.
Swift proporciona cuatro niveles de acceso diferentes para las entidades en el código:public、internal、fileprivate、private。
| Nivel de acceso | Definición |
|---|---|
| public | Puede acceder a cualquier entidad en un archivo fuente dentro de su propio módulo, y otros también pueden acceder a todas las entidades en el archivo fuente al introducir ese módulo. |
| internal | Puede acceder a cualquier entidad en un archivo fuente dentro de su propio módulo, pero otros no pueden acceder a las entidades en los archivos fuente de ese módulo. |
| fileprivate | Privado dentro del archivo, solo se puede usar en el archivo fuente actual. |
| private | Solo se puede acceder dentro de la clase; fuera del ámbito de esa clase o estructura no se puede acceder. |
public es el nivel de acceso más alto, private es el nivel de acceso más bajo.
Sintaxis
Declara el nivel de acceso de una entidad mediante los modificadores public, internal, fileprivate, private:
Ejemplo
A menos que se indique lo contrario, las entidades usan el nivel de acceso predeterminado internal.
Si no se especifica un nivel de acceso, el valor predeterminado es internal
Permisos de acceso de tipos de función
El nivel de acceso de una función debe derivarse del nivel de acceso del tipo de sus parámetros y de su tipo de retorno.
El siguiente ejemplo define una función global llamada someFunction, y no declara explícitamente su nivel de acceso.
func someFunction() -> (SomeInternalClass, SomePrivateClass) {
// 函数实现
}
En la función, una de las clases, SomeInternalClass, tiene un nivel de acceso internal, y la otra, SomePrivateClass, tiene un nivel de acceso private. Por lo tanto, según el principio del nivel de acceso de tuplas, el nivel de acceso de esta tupla es private (el nivel de acceso de una tupla es el mismo que el del tipo con el nivel más bajo dentro de la tupla).
Debido a que el nivel de acceso del tipo de retorno de esta función es private, debes usar el modificador private para declarar explícitamente la función:
private func someFunction() -> (SomeInternalClass, SomePrivateClass) {
// 函数实现
}
Declarar la función como public o internal, o usar el nivel de acceso predeterminado internal, es incorrecto, porque si lo haces no podrás acceder al valor de retorno de nivel private.
Permisos de acceso de tipos de enumeración
El nivel de acceso de los miembros de una enumeración se hereda de la propia enumeración; no puedes declarar individualmente un nivel de acceso diferente para los miembros de la enumeración.
Ejemplo
Por ejemplo, en el siguiente ejemplo, la enumeración Student está declarada explícitamente como nivel public, por lo que sus miembros Name y Mark también tienen el nivel de acceso public:
Ejemplo
El resultado de la ejecución del programa anterior es:
学生成绩: 98,97,95
Permisos de acceso de subclases
El nivel de acceso de una subclase no debe ser superior al de su superclase. Por ejemplo, si el nivel de acceso de la superclase es internal, el nivel de acceso de la subclase no puede declararse como public.
Ejemplo
El resultado de la ejecución del programa anterior es:
Superclase
Permisos de acceso de constantes, variables, propiedades y subíndices
Las constantes, variables y propiedades no pueden tener un nivel de acceso más alto que el de sus tipos.
Por ejemplo, si defines una propiedad de nivel public, pero su tipo es de nivel private, el compilador no lo permite.
Del mismo modo, un subíndice no puede tener un nivel de acceso más alto que el tipo de índice o el tipo de retorno.
Si los tipos de definición de constantes, variables, propiedades e índices de subíndice son de nivel private, entonces deben declarar explícitamente su nivel de acceso como private:
private var privateInstance = SomePrivateClass()
Permisos de acceso de Getter y Setter
Los niveles de acceso de los Getters y Setters de constantes, variables, propiedades e índices de subíndice se heredan del nivel de acceso del miembro al que pertenecen.
El nivel de acceso de un Setter puede ser más bajo que el nivel de acceso del Getter correspondiente, de modo que se puedan controlar los permisos de lectura y escritura de variables, propiedades o índices de subíndice.
Ejemplo
El nivel de acceso de counter es fileprivate, se puede acceder a él dentro del archivo.
El resultado de la ejecución del programa anterior es:
计数器: 100 新增加数量 100 计数器: 800 新增加数量 700
Permisos de acceso de inicializadores e inicializadores predeterminados
Inicialización
Podemos declarar un nivel de acceso para los métodos de inicialización personalizados, pero no debe ser superior al nivel de acceso de la clase a la que pertenecen. Sin embargo, los inicializadores requeridos son una excepción; su nivel de acceso debe ser el mismo que el de la clase a la que pertenecen.
Al igual que los parámetros de funciones o métodos, el nivel de acceso de los parámetros de un método de inicialización no puede ser más bajo que el nivel de acceso del método de inicialización.
Método de inicialización predeterminado
Swift proporciona un método de inicialización predeterminado sin parámetros para estructuras y clases, que se utiliza para asignar valores a todas sus propiedades, pero no proporciona valores específicos.
El nivel de acceso del método de inicialización predeterminado es el mismo que el nivel de acceso del tipo al que pertenece.
Ejemplo
Usa la palabra clave required antes del método init() de cada subclase para declarar el permiso de acceso.
Ejemplo
El resultado de la ejecución del programa anterior es:
10 30 10
Permisos de acceso de protocolos
Si deseas declarar explícitamente un nivel de acceso para un protocolo, debes tener en cuenta que debes asegurarte de que el protocolo solo se use dentro del ámbito del nivel de acceso que declaras.
Si defines un protocolo de nivel public, las funciones necesarias para implementar ese protocolo también tendrán nivel de acceso public. Esto es diferente de otros tipos; por ejemplo, en otros tipos de nivel public, el nivel de acceso de sus miembros es internal.
Ejemplo
El resultado de la ejecución del programa anterior es:
res is: 20 res is: 30 res is: 50
Permisos de acceso de extensiones
Puedes extender clases, estructuras y enumeraciones cuando las condiciones lo permitan. Los miembros de la extensión deben tener el mismo nivel de acceso que los miembros del tipo original. Por ejemplo, si extiendes un tipo público, los nuevos miembros que agregues deben tener el mismo nivel de acceso predeterminado internal que los miembros originales.
Alternativamente, puedes declarar explícitamente el nivel de acceso de la extensión (por ejemplo, usando private extension) para declarar un nuevo nivel de acceso predeterminado para todos los miembros dentro de la extensión. Este nuevo nivel de acceso predeterminado aún puede ser anulado por el nivel de acceso declarado por miembros individuales.
Permisos de acceso de genéricos
El nivel de acceso de un tipo genérico o función genérica es el nivel de acceso más bajo entre el tipo genérico, la función en sí y los parámetros de tipo genérico.
Ejemplo
El resultado de la ejecución del programa anterior es:
["Swift"] ["Swift", "泛型"] ["Swift", "泛型", "类型参数"] ["Swift", "泛型", "类型参数", "类型参数名"]
Alias de tipo
Cualquier alias de tipo que definas se tratará como un tipo diferente para facilitar el control de acceso. El nivel de acceso de un alias de tipo no puede ser superior al nivel de acceso del tipo original.
Por ejemplo, un alias de tipo de nivel private se puede asignar a un tipo public, internal o private, pero un alias de tipo de nivel public solo se puede asignar a un tipo de nivel public, no a un tipo de nivel internal o private.
Nota: esta regla también se aplica al caso de nombrar alias para tipos relacionados con el fin de cumplir con la conformidad de protocolos.
Ejemplo
El resultado de la ejecución del programa anterior es:
["Swift"] ["Swift", "泛型"] ["Swift", "泛型", "Where 语句"] ["Swift", "泛型", "Where 语句"]Otras extensiones