Clases anidadas y clases internas
Dentro de una clase se puede definir otra clase que se conoce como clase anidada (Nested Class), y como esta clase anidada es miembro de la clase exterior, se puede usar la notación del punto para acceder a la clase anidada y a sus miembros:
class Exterior { val a = "Fuera de la clase Anidada" class Anidada { val b = "Dentro de la clase Anidada." fun funAnidada() = "LLamada a la función desde la clase Anidada." } } fun main() { // acceso al miembro de la clase Exterior println(Exterior().a) // acceso al miembro de la clase Anidada println(Exterior.Anidada().b) // creación de un objeto de la clase Anidada val anidada = Exterior.Anidada() println(anidada.funAnidada()) }
Pero las clases anidadas no tienen acceso a las instancias de la clase externa. Por ejemplo, en el código anterior desde la clase 'Anidada' no podemos acceder a la propiedad 'a' de la clase 'Exterior'. Para resolver este problema debemos marcar la clase anidada con inner para crear una clase interior o interna (Inner Class) puesto que las clases internas conllevan una referencia a la clase externa y por tanto pueden acceder a sus miembros.
class Externa { val a = "Fuera de la clase Anidada" inner class Interna { fun funInterna() = a } } fun main() { println(Externa().Interna().funInterna()) }
A veces es posible que las variables o funciones de las clases externa e interna tengan el mismo nombre, y en estos casos usamos la palabra clave this@ para especificar desde qué clase desea acceder a esa variable o función (si no se especifica de esta manera, por defecto Kotlin verifica las variables y funciones en la clase interna antes de referirse a la clase externa).
class Externa { var numero = 0 inner class Interna { private var numero = 1 fun funInterna() { println(this@Externa.numero) // 0 println(this@Interna.numero) // 1 } } } fun main() { Externa().Interna().funInterna() }
Aunque ahora no nos vamos a detener en esto, la clase interna puede ser anónima utilizando una expresión de objeto:
interface Empleado { fun hace() } fun main() { // creamos una instancia de la interfaz Empleado val programador: Empleado = object : Empleado { override fun hace() { // sobrescribe el método println("Ejemplo de clase interna anónima") } } programador.hace() }
Comentarios
Publicar un comentario