proteccion niveles functions acceso access-modifiers swift

access-modifiers - niveles - public c#



¿Swift tiene modificadores de acceso? (17)

Mecanismos de control de acceso introducidos en Xcode 6 :

Swift proporciona tres niveles de acceso diferentes para las entidades dentro de su código. Estos niveles de acceso son relativos al archivo fuente en el que se define una entidad y también al módulo al que pertenece el archivo fuente.

  • El acceso público permite que las entidades se utilicen dentro de cualquier archivo de origen desde su módulo de definición, y también en un archivo de origen de otro módulo que importa el módulo de definición. Normalmente, se utiliza el acceso público cuando se especifica la interfaz pública a un marco.
  • El acceso interno permite que las entidades se usen dentro de cualquier archivo fuente desde su módulo de definición, pero no en ningún archivo fuente fuera de ese módulo. Normalmente, se utiliza el acceso interno al definir una estructura interna de una aplicación o de un marco.
  • El acceso privado restringe el uso de una entidad a su propio archivo fuente de definición. Utilice el acceso privado para ocultar los detalles de implementación de una pieza específica de funcionalidad.

El acceso público es el nivel de acceso más alto (menos restrictivo) y el acceso privado es el nivel de acceso más bajo (o más restrictivo).

El acceso predeterminado es interno y, como tal, no necesita ser especificado. También tenga en cuenta que el especificador privado no funciona en el nivel de clase, sino en el nivel de archivo de origen. Esto significa que para obtener partes de una clase realmente privada debe separarse en un archivo propio. Esto también introduce algunos casos interesantes con respecto a las pruebas unitarias ...

Otro punto que me comentaron, que se comenta en el enlace anterior, es que no se puede "actualizar" el nivel de acceso. Si subclasifica algo, puede restringirlo más, pero no al revés.

Este último bit también afecta a las funciones, a las tuplas y, seguramente, a otras cosas en la forma en que si, por ejemplo, una función utiliza una clase privada , entonces no es válido tener la función interna o pública , ya que es posible que no tengan acceso a la clase privada . Esto da como resultado una advertencia del compilador, y debe volver a declarar la función como una función privada .

En la instancia de Objective-C, los datos pueden ser public , protected o private . Por ejemplo:

@interface Foo : NSObject { @public int x; @protected: int y; @private: int z; } -(int) apple; -(int) pear; -(int) banana; @end

No he encontrado ninguna mención de modificadores de acceso en la referencia Swift. ¿Es posible limitar la visibilidad de los datos en Swift?


Swift 4

Como se menciona en la documentación de Swift - Control de acceso , Swift 4 tiene 5 controles de acceso :

  • abierto y público : se puede acceder desde las entidades de su módulo y desde cualquier módulo que importe el módulo de definición.

  • interno : solo se puede acceder desde las entidades de sus módulos. Es el nivel de acceso predeterminado.

  • fileprivate y private : solo se puede acceder de forma limitada dentro de un alcance limitado donde se definen.


¿Cuál es la diferencia entre abierto y público ?

open es lo mismo que public en las versiones anteriores de Swift, permiten que las clases de otros módulos las utilicen y las hereden, es decir, se pueden subclasificar desde otros módulos. Además, permiten que los miembros de otros módulos los utilicen y los anulen. La misma lógica va para sus módulos.

Las clases públicas permiten que las clases de otros módulos las utilicen, pero no las hereden, es decir, no pueden ser subclasificadas de otros módulos. Además, permiten que los miembros de otros módulos los utilicen, pero NO los anulen. Para sus módulos, tienen la misma lógica de apertura (permiten que las clases las usen y las heredan; les permiten a los miembros usarlas y las anulan).


¿Cuál es la diferencia entre filiprivado y privado ?

Se puede acceder a fileprivate desde sus archivos completos.

Privado solo se puede acceder desde su declaración única y a las extensiones de esa declaración que están en el mismo archivo; Por ejemplo:

// Declaring "A" class that has the two types of "private" and "fileprivate": class A { private var aPrivate: String? fileprivate var aFileprivate: String? func accessMySelf() { // this works fine self.aPrivate = "" self.aFileprivate = "" } } // Declaring "B" for checking the abiltiy of accessing "A" class: class B { func accessA() { // create an instance of "A" class let aObject = A() // Error! this is NOT accessable... aObject.aPrivate = "I CANNOT set a value for it!" // this works fine aObject.aFileprivate = "I CAN set a value for it!" } }


¿Cuáles son las diferencias entre Swift 3 y Swift 4 Access Control?

Como se mencionó en la propuesta SE-0169 , el único refinamiento que se agregó a Swift 4 es que el alcance del control de acceso privado se ha expandido para ser accesible desde las extensiones de esa declaración en el mismo archivo; Por ejemplo:

struct MyStruct { private let myMessage = "Hello World" } extension MyStruct { func printMyMessage() { print(myMessage) // In Swift 3, you will get a compile time error: // error: ''myMessage'' is inaccessible due to ''private'' protection level // In Swift 4 it should works fine! } }

Por lo tanto, no es necesario declarar myMessage como fileprivate para que sea accesible en todo el archivo.

Nota de la barra lateral: Si enfrentó problemas relacionados con no compilar Swift 4 con un proyecto Swift 3 migrado anterior, puede consultar esta sección de preguntas y respuestas .


A partir de Xcode 6 beta 4, Swift tiene modificadores de acceso. De las notas de publicación:

El control de acceso rápido tiene tres niveles de acceso:

  • Solo se puede acceder a las entidades privadas desde dentro del archivo fuente donde están definidas.
  • Se puede acceder a las entidades internas en cualquier lugar dentro del objetivo donde se definen.
  • Se puede acceder a las entidades públicas desde cualquier lugar dentro del objetivo y desde cualquier otro contexto que importe el módulo del objetivo actual.

El valor predeterminado implícito es internal , por lo que, dentro de un objetivo de la aplicación, puede dejar desactivados los modificadores de acceso, excepto cuando desee ser más restrictivo. En un objetivo de marco (por ejemplo, si está incrustando un marco para compartir código entre una aplicación y una extensión de vista compartida o Hoy), use public para designar la API que desea exponer a los clientes de su marco.


Ahora en la beta 4, han agregado modificadores de acceso a Swift.

de Xcode 6 beta 4 notas reales :

El control de acceso rápido tiene tres niveles de acceso:

  • Solo se puede acceder a private entidades private desde el archivo de origen donde se definen.
  • Se puede acceder a internal entidades internal cualquier lugar dentro del objetivo donde se definen.
  • Se puede acceder a public entidades public desde cualquier lugar dentro del objetivo y desde cualquier otro contexto que importe el módulo del objetivo actual.

Por defecto, la mayoría de las entidades en un archivo fuente tienen acceso interno. Esto permite a los desarrolladores de aplicaciones ignorar en gran medida el control de acceso al tiempo que les permite a los desarrolladores del marco el control total sobre la API de un marco.


Con suerte, para ahorrar algo de tiempo para aquellos que quieren algo parecido a los métodos protegidos:

Según otras respuestas, swift ahora proporciona el modificador ''privado'', que se define por archivo en lugar de por clase, como los de Java o C #, por ejemplo. Esto significa que si desea métodos protegidos, puede hacerlo con métodos privados rápidos si están en el mismo archivo

  1. Cree una clase base para mantener los métodos ''protegidos'' (en realidad, privados)
  2. Subclase esta clase para usar los mismos métodos.
  3. En otros archivos, no puede acceder a los métodos de clase base, incluso cuando subclase

Ej. Archivo 1:

class BaseClass { private func protectedMethod() { } } class SubClass : BaseClass { func publicMethod() { self.protectedMethod() //this is ok as they are in same file } }

Archivo 2:

func test() { var a = BaseClass() a.protectedMethod() //ERROR var b = SubClass() b.protectedMethod() //ERROR } class SubClass2 : BaseClass { func publicMethod() { self.protectedMethod() //ERROR }

}


Cuando se habla de hacer un "método privado" en Swift u ObjC (o ruby ​​o java o ...), esos métodos no son realmente privados. No hay control de acceso real alrededor de ellos. Cualquier lenguaje que ofrezca incluso una pequeña introspección permite a los desarrolladores obtener esos valores de fuera de la clase si realmente lo desean.

Entonces, de lo que realmente estamos hablando aquí es una forma de definir una interfaz orientada al público que simplemente presenta la funcionalidad que queremos y "oculta" el resto que consideramos "privado".

El mecanismo Swift para declarar interfaces es el protocol , y puede usarse para este propósito.

protocol MyClass { var publicProperty:Int {get set} func publicMethod(foo:String)->String } class MyClassImplementation : MyClass { var publicProperty:Int = 5 var privateProperty:Int = 8 func publicMethod(foo:String)->String{ return privateMethod(foo) } func privateMethod(foo:String)->String{ return "Hello /(foo)" } }

Recuerde, los protocolos son tipos de primera clase y pueden usarse en cualquier lugar que un tipo pueda. Y , cuando se usan de esta manera, solo exponen sus propias interfaces, no las del tipo de implementación.

Por lo tanto, siempre que use MyClass lugar de MyClassImplementation en sus tipos de parámetros, etc., todo debería funcionar:

func breakingAndEntering(foo:MyClass)->String{ return foo.privateMethod() //ERROR: ''MyClass'' does not have a member named ''privateMethod'' }

Hay algunos casos de asignación directa en los que tiene que ser explícito con el tipo en lugar de confiar en Swift para inferirlo, pero eso no parece ser un factor decisivo:

var myClass:MyClass = MyClassImplementation()

El uso de protocolos de esta manera es semántico, razonablemente conciso y, a mi modo de ver, se parece mucho a las Extensiones de clase que hemos estado utilizando para este propósito en ObjC.


En Beta 6, la documentación indica que hay tres modificadores de acceso diferentes:

  • Público
  • Interno
  • Privado

Y estos tres se aplican a Clases, Protocolos, funciones y propiedades.

public var somePublicVariable = 0 internal let someInternalConstant = 0 private func somePrivateFunction() {}

Para más información, consulte Control de acceso .


La gramática del idioma no tiene las palabras clave ''pública'', ''privada'' o ''protegida''. Esto sugeriría que todo es público. Por supuesto, podría haber algún método alternativo para especificar modificadores de acceso sin esas palabras clave, pero no pude encontrarlo en la referencia del idioma.


No, no es posible. No hay ningún método privado / protegido y variables en absoluto.

Todo es público.


Por lo que puedo decir, no hay palabras clave ''públicas'', ''privadas'' o ''protegidas''. Esto sugeriría que todo es público.

Sin embargo, Apple puede estar esperando que la gente use " protocols " (llamados interfaces por el resto del mundo) y el patrón de diseño de fábrica para ocultar los detalles del tipo de implementación.

Este es a menudo un buen patrón de diseño para usar de todos modos; ya que le permite cambiar su jerarquía de clases de implementación , al mismo tiempo que mantiene el sistema de tipos lógicos igual.


Una de las opciones que podría usar es envolver la creación de la instancia en una función y proporcionar a los captadores y definidores apropiados en un constructor:

class Counter { let inc: () -> Int let dec: () -> Int init(start: Int) { var n = start inc = { ++n } dec = { --n } } } let c = Counter(start: 10) c.inc() // 11 c.inc() // 12 c.dec() // 11


Usando una combinación de protocolos, cierres y clases anidadas / internas, es posible usar algo a lo largo de las líneas del patrón del módulo para ocultar la información en Swift ahora mismo. No es súper limpio ni agradable de leer, pero funciona.

Ejemplo:

protocol HuhThing { var huh: Int { get set } } func HuhMaker() -> HuhThing { class InnerHuh: HuhThing { var innerVal: Int = 0 var huh: Int { get { return mysteriousMath(innerVal) } set { innerVal = newValue / 2 } } func mysteriousMath(number: Int) -> Int { return number * 3 + 2 } } return InnerHuh() } HuhMaker() var h = HuhMaker() h.huh // 2 h.huh = 32 h.huh // 50 h.huh = 39 h.huh // 59

innerVal y mysteriousMath están ocultos aquí para uso externo y el intento de abrirse camino en el objeto debería generar un error.

Soy solo una parte del camino a través de mi lectura de los documentos de Swift, así que si hay una falla aquí, por favor, señálelo, me encantaría saberlo.


hasta Swift 2.0 solo había tres niveles de acceso [Público, interno, privado] pero en Swift 3.0 Apple agregó dos nuevos niveles de acceso que son [Abrir, tipo de archivo], por lo que ahora en Swift 3.0 hay 5 niveles de acceso. Aquí quiero borrar el rol de estos dos niveles de acceso 1. Abierto: esto es muy similar al Público, pero la única diferencia es que el Público puede acceder a la subclase y anularlo, y el Nivel de acceso abierto no puede acceder a que esta imagen se toma del sitio web de Medium y esto describe la diferencia entre acceso abierto y público

Ahora, al segundo nuevo nivel de acceso 2. El tipo de archivo es una versión más grande de un nivel de acceso privado o inferior al interno. El tipo de archivo puede acceder a la parte extendida de [class, struct, enum] y private no puede acceder a la parte extendida del código al que solo puede acceder el ámbito léxico de esta imagen se toma del sitio web de Medium y describe la diferencia entre fileType y el nivel de acceso privado


A partir de Swift 3.0.1 , hay 4 niveles de acceso , que se describen a continuación, desde el más alto (el menos restrictivo) hasta el más bajo (el más restrictivo).

1. open y public

Permitir que una entidad se utilice fuera del módulo de definición (destino). Por lo general, se utiliza public acceso open o public al especificar la interfaz pública a un marco.

Sin embargo, open acceso open aplica solo a las clases y los miembros de la clase , y se diferencia del acceso public de public siguiente manera:

  • public clases public y los miembros de la clase solo pueden clasificarse y anularse dentro del módulo de definición (destino).
  • open clases open y los miembros de la clase pueden clasificarse y reemplazarse tanto dentro como fuera del módulo de definición (destino).

// First.framework – A.swift open class A {}

// First.framework – B.swift public class B: A {} // ok

// Second.framework – C.swift import First internal class C: A {} // ok

// Second.framework – D.swift import First internal class D: B {} // error: B cannot be subclassed

2. internal

Permite que una entidad se utilice dentro del módulo de definición (destino). Normalmente, se utiliza internal acceso internal al definir una estructura interna de una aplicación o de un marco.

// First.framework – A.swift internal struct A {}

// First.framework – B.swift A() // ok

// Second.framework – C.swift import First A() // error: A is unavailable

3. fileprivate

Restringe el uso de una entidad a su archivo fuente de definición. Por lo general, se usa el acceso fileprivate a fileprivate para ocultar los detalles de implementación de una pieza específica de funcionalidad cuando esos detalles se usan dentro de un archivo completo.

// First.framework – A.swift internal struct A { fileprivate static let x: Int } A.x // ok

// First.framework – B.swift A.x // error: x is not available

4. private

Restringe el uso de una entidad a su declaración adjunta. Normalmente, se usa private acceso private para ocultar los detalles de implementación de una pieza específica de funcionalidad cuando esos detalles se usan solo dentro de una declaración.

// First.framework – A.swift internal struct A { private static let x: Int internal static func doSomethingWithX() { x // ok } } A.x // error: x is unavailable



Swift 3 y 4 trajeron muchos cambios también para los niveles de acceso de las variables y los métodos. Swift 3 y 4 ahora tiene 4 niveles de acceso diferentes, donde el acceso abierto / público es el nivel de acceso más alto (menos restrictivo) y el acceso privado es el nivel de acceso más bajo (más restrictivo):

  • Solo se puede acceder a las funciones y miembros privados desde el ámbito de la propia entidad (estructura, clase, ...) y sus extensiones (en Swift 3 también se restringieron las extensiones)
  • Solo se puede acceder a las funciones y miembros de fileprivate desde el archivo de origen donde se declaran.
  • se puede acceder a las funciones internas y a los miembros (que es el valor predeterminado, si no agrega explícitamente una palabra clave de nivel de acceso) en cualquier lugar dentro del destino donde se definen. Por eso, TestTarget no tiene acceso automático a todas las fuentes, tienen que estar marcadas como accesibles en el inspector de archivos de xCode.
  • Se puede acceder a las funciones y miembros abiertos o públicos desde cualquier lugar dentro del destino y desde cualquier otro contexto que importe el módulo del objetivo actual.

Interesante:

En lugar de marcar cada método o miembro como "privado", puede cubrir algunos métodos (por ejemplo, las funciones de ayuda) en una extensión de una clase / estructura y marcar la extensión completa como "Privada".

class foo { } private extension foo { func somePrivateHelperFunction01() { } func somePrivateHelperFunction02() { } func somePrivateHelperFunction03() { } }

Esto puede ser una buena idea para obtener un mejor código de mantenimiento. Y puede cambiar fácilmente (por ejemplo, para pruebas unitarias) a no privado simplemente cambiando una palabra.

Documentación de apple


Swift 3.0 proporciona cinco controles de acceso diferentes:

  1. abierto
  2. público
  3. interno
  4. filiprivado
  5. privado

El acceso abierto y el acceso público permiten que las entidades se utilicen dentro de cualquier archivo de origen desde su módulo de definición, y también en un archivo de origen de otro módulo que importe el módulo de definición. Por lo general, se utiliza el acceso abierto o público al especificar la interfaz pública a un marco.

El acceso interno permite que las entidades se usen dentro de cualquier archivo fuente desde su módulo de definición, pero no en ningún archivo fuente fuera de ese módulo. Normalmente, se utiliza el acceso interno al definir una estructura interna de una aplicación o de un marco.

El acceso privado al archivo restringe el uso de una entidad a su propio archivo fuente de definición. Utilice el acceso privado al archivo para ocultar los detalles de la implementación de una pieza específica de funcionalidad cuando esos detalles se usan dentro de un archivo completo.

El acceso privado restringe el uso de una entidad a la declaración adjunta. Use el acceso privado para ocultar los detalles de implementación de una pieza específica de funcionalidad cuando esos detalles se usan solo dentro de una declaración.

El acceso abierto es el nivel de acceso más alto (menos restrictivo) y el acceso privado es el nivel de acceso más bajo (más restrictivo).

Niveles de acceso predeterminados

Todas las entidades en su código (con unas pocas excepciones específicas) tienen un nivel de acceso predeterminado de interno si usted no especifica un nivel de acceso explícito. Como resultado, en muchos casos no necesita especificar un nivel de acceso explícito en su código.

La nota de lanzamiento sobre el tema:

Las clases declaradas como públicas ya no pueden ser subclasificadas fuera de su módulo de definición, y los métodos declarados como públicos ya no pueden ser anulados fuera de su módulo de definición. Para permitir que una clase sea subclasificada externamente o que un método sea anulado externamente, declararlos como abiertos, que es un nuevo nivel de acceso más allá del público. Las clases y métodos de Objective-C importados ahora se importan como abiertos en lugar de públicos. Las pruebas unitarias que importan un módulo utilizando una importación comprobable en @ todavía se podrán subclasificar en clases públicas o internas, así como sobreescribir métodos públicos o internos. (SE-0117)

Más información y detalles: El lenguaje de programación Swift (Control de acceso)