ProgramaciónDesarrollador de Android

¿Cómo funcionan los modificadores de visibilidad en Kotlin: internal, private, protected, public? ¿Cuáles son las diferencias de los modificadores en diferentes contextos, como para clases, funciones, propiedades, objetos, funciones de nivel superior y archivos?

Supere entrevistas con el asistente de IA Hintsage

Respuesta

En Kotlin existen los siguientes modificadores de visibilidad:

  • public (por defecto): el elemento es visible en todas partes.
  • internal: el elemento es visible dentro de un módulo (jar/módulo gradle, etc.).
  • protected: visible solo dentro de la clase y sus subclases.
  • private: visible solo dentro del archivo o clase.

Particularidades:

  • Para funciones, propiedades y clases de nivel superior: private limita el acceso al ámbito del archivo, internal al módulo y public/protected no tiene sentido fuera de la clase.
  • Para miembros de clase: private es solo dentro de esa clase, protected — más subclases, internal y public — como se describió anteriormente.
  • Dentro de un objeto/companion object: análogo a la clase.
class MyClass { private val secret = "hidden" protected val id = 42 internal fun foo() {} public fun bar() {} } internal fun moduleFunc() {} private fun fileOnlyFunc() {}

Pregunta capciosa

"¿Puede una función de nivel superior ser protected? Si es así, ¿cómo funciona? Si no, ¿por qué?"

Respuesta: No, una función de nivel superior no puede ser protected, ya que no hay una clase a la que pertenezca este nivel de acceso. Esto es controlado por el compilador: se generará un error de compilación.

protected fun magic() {} // Error: el modificador protected no está permitido para funciones de nivel superior

Ejemplos de errores reales debido a la falta de conocimiento de los matices del tema


Historia

En una aplicación fintech, se olvidaron de que el modificador internal permite el acceso a todos los elementos del módulo. Como resultado, al refactorizar, trasladaron parte de la lógica a otro módulo gradle, después de lo cual el acceso a los datos dejó de funcionar, pero los desarrolladores no lo notaron de inmediato, ya que no hubo errores de compilación en las pruebas antiguas.


Historia

En un proyecto multiplataforma, definieron datos confidenciales como propiedades private en un companion object. Resultó que estos datos se serializaban y se volvían accesibles a través de reflection, porque se declararon como val sin usar anotaciones que limitaran la exportación.


Historia

Al inicio de un proyecto móvil, aplicaron private a funciones de nivel superior, suponiendo que esto limitaría el acceso a clases asociadas. Sin embargo, dentro de un archivo común con utils, estas funciones eran visibles para todos, lo que llevó a una amenaza de fuga de información y un uso imprevisto en la lógica comercial.