En Swift hay cinco niveles de acceso a los miembros de tipos (propiedades, métodos, etc.) y a los propios tipos:
open — el grado máximo de publicitación. Se puede heredar y sobrescribir incluso fuera del módulo.public — accesible fuera del módulo, pero no se puede sobrescribir/heredar.internal (por defecto) — accesible dentro del módulo.fileprivate — accesible solo dentro del archivo.private — accesible solo dentro del ámbito de la declaración (el extension también está en este ámbito).private para la lógica que no debe ser visible fuera de la declaración.fileprivate — si se necesita intercambiar datos en un mismo archivo (por ejemplo, entre dos extensions relacionadas).internal — el valor por defecto para todo lo público en el módulo.public/open — para API utilizadas por otros módulos/frameworks.open class MyOpenClass {} public class MyPublicClass {} internal class InternalClass {} fileprivate class FilePrivateClass {} private class PrivateClass {}
¿Cuál es la diferencia entre open y public al describir una clase? ¿Por qué no todas las clases public son accesibles para heredar?
Respuesta:
open marca una clase/método como accesible para sobrescribir y heredar fuera de su módulo. public solo abre el acceso para el uso, pero no permite crear herederos fuera del módulo. Por un lado, esto protege la implementación de cambios no deseados, y por otro, abre solo los puntos de extensión necesarios.
public class PublicClass {} open class OpenClass {} // En otro módulo: class InheritFromOpen: OpenClass {} // OK class InheritFromPublic: PublicClass {} // ¡Error!
Historia
En una biblioteca común, una clase fue marcada como public, y un proyecto externo intentó extenderla sobrescribiendo métodos. El proyecto no compilaba debido a un entendimiento erróneo de la diferencia entre public y open — esto le costó al equipo una semana adicional para ajustar la interfaz.
Historia
Dentro de un archivo, se intentó acceder a una propiedad privada desde un extension — pero la propiedad fue declarada no como fileprivate, sino como private. Esto llevó a un error del compilador que solo se notó en la construcción de integración.
Historia
En una aplicación con varios frameworks, todos los tipos estaban marcados como internal (por defecto). Cuando fue necesario usar tipos entre los módulos, la interfaz no estaba disponible — se tuvo que reescribir decenas de declaraciones a public, lo que tomó tiempo adicional y pruebas.