Kotlin es un lenguaje de programación moderno que compila a bytecode Java. Es gratuito y de código abierto, y promete hacer que la codificación para Android sea aún más divertida.
En el artículo anterior, aprendió más sobre las propiedades de Kotlin, como las propiedades de inicialización tardía, extensión y en línea. No solo eso, también aprendió sobre clases avanzadas como clases de datos, enumeración, anidadas y selladas en Kotlin.
En esta publicación, continuará aprendiendo sobre la programación orientada a objetos en Kotlin aprendiendo sobre clases abstractas, interfaces y herencia. Para obtener una bonificación, también aprenderá sobre los alias de tipo.
Kotlin admite clases abstractas; al igual que Java, estas son clases de las que nunca intentará crear objetos. Una clase abstracta es incompleta o inútil sin algunas subclases concretas (no abstractas), desde las cuales puede instanciar objetos. Una subclase concreta de una clase abstracta implementa todos los métodos y propiedades definidos en la clase abstracta; de lo contrario, esa subclase también es una clase abstracta!
Creamos una clase abstracta con el resumen
modificador (similar a Java).
empleado de la clase abstracta (nombre de pila val: cadena, apellido de val: cadena) ganancias abstractas divertidas (): doble
Tenga en cuenta que no todos los miembros tienen que ser abstractos. En otras palabras, podemos tener la implementación predeterminada del método en una clase abstracta.
empleado de la clase abstracta (primer nombre de val: String, apellido de val: String) //… fun fullName (): String return lastName + "" + firstName;
Aquí creamos la función no abstracta. nombre completo()
en una clase abstracta Empleado
. Las clases concretas (subclases de la clase abstracta) pueden anular la implementación predeterminada de un método abstracto, pero solo si el método tiene la abierto
modificador especificado (aprenderá más sobre esto en breve).
También podemos almacenar el estado en clases abstractas..
clase abstracta Empleado (nombre de pila val: cadena, apellido de val: cadena) // ... val propFoo: cadena = "bla bla"
Incluso si la clase abstracta no define ningún método, debemos crear una subclase antes de poder crear una instancia, como se muestra en el siguiente ejemplo..
Programador de clase (nombre de pila: cadena, apellido de cadena: cadena): empleado (nombre de pila, apellido) anular ganancias por diversión (): doble // calcular ganancias
Nuestro Programador
clase extiende el Empleado
clase abstracta. En Kotlin usamos un solo carácter de dos puntos (:
) en lugar de Java se extiende
palabra clave para ampliar una clase o implementar una interfaz.
Podemos entonces crear un objeto de tipo. Programador
y llamar a los métodos en él, ya sea en su propia clase o en la superclase (clase base).
val programmer = Programmer ("Chike", "Mgbemena") println (programmer.fullName ()) // "Mgbemena Chike"
Una cosa que podría sorprenderlo es que tenemos la capacidad de anular un val
(Inmutable) propiedad con var
(mudable).
clase abierta BaseA (open val baseProp: String) clase DerivedA: BaseA ("") private var derivadaProp: String = "" sobrescribe var baseProp: String get () = derivadaProp set (valor) derivadoProp = valor
¡Asegúrate de usar esta funcionalidad sabiamente! Tenga en cuenta que no podemos hacer la anulación inversa de un var
propiedad con val
.
Una interfaz es simplemente una colección de métodos relacionados que normalmente le permiten decirle a los objetos qué hacer y también cómo hacerlo de forma predeterminada. (Los métodos predeterminados en las interfaces son una nueva característica agregada a Java 8). En otras palabras, una interfaz es un contrato que las clases implementadoras deben cumplir.
Una interfaz se define utilizando la interfaz
palabra clave en Kotlin (similar a Java).
clase Resultado clase Interfaz del estudiante StudentRepository fun getById (id: Long): Student fun getResultsById (id: Long): List
En el código anterior, hemos declarado un Repositorio de estudiantes
interfaz. Esta interfaz contiene dos métodos abstractos: getById ()
y getResultsById ()
. Tenga en cuenta que incluyendo el resumen
palabra clave es redundante en un método de interfaz porque ya están implícitamente abstractos.
Una interfaz es inútil sin uno o más implementadores, así que vamos a crear una clase que implementará esta interfaz.
clase StudentLocalDataSource: StudentRepository override fun getResults (id: Long): List// hacer implementación anular la diversión getById (id: Long): Estudiante // hacer implementación
Aquí creamos una clase. StudentLocalDataSource
que implementa el Repositorio de estudiantes
interfaz.
Usamos el anular
modificador para etiquetar los métodos y propiedades que queremos redefinir desde la interfaz o superclase; esto es similar a la @Anular
anotación en java.
Tenga en cuenta las siguientes reglas adicionales de interfaces en Kotlin:
anular
El modificador es obligatorio en Kotlin, a diferencia de Java.. Veamos un ejemplo de un método de interfaz con una implementación predeterminada..
interfaz StudentRepository // ... fun delete (student: Student) // do implementación
En el código anterior, agregamos un nuevo método. borrar()
con una implementación predeterminada (aunque no agregué el código de implementación real para fines de demostración).
También tenemos la libertad de anular la implementación predeterminada si queremos.
clase StudentLocalDataSource: StudentRepository // ... override fun delete (estudiante: Estudiante) // hacer implementación
Como se indicó, una interfaz de Kotlin puede tener propiedades, pero tenga en cuenta que no puede mantener el estado. (Sin embargo, recuerde que las clases abstractas pueden mantener el estado). Por lo tanto, la siguiente definición de interfaz con una declaración de propiedad funcionará.
interfaz StudentRepository val propFoo: Boolean // funcionará //…
Pero si intentamos agregar algún estado a la interfaz asignando un valor a la propiedad, no funcionará.
interface StudentRepository val propFoo: Boolean = true // Error: No se permiten inicializadores de propiedades en las interfaces // ...
Sin embargo, una propiedad de interfaz en Kotlin puede tener métodos de obtención y establecimiento (aunque solo este último si la propiedad es mutable). Tenga en cuenta también que la propiedad en una interfaz no puede tener un campo de respaldo.
interfaz StudentRepository var propFoo: Boolean get () = true set (value) if (value) // hacer algo //…
También podemos anular una propiedad de la interfaz si lo desea, para redefinirla.
clase StudentLocalDataSource: StudentRepository // ... override var propFoo: Boolean get () = false set (value) if (value)
Veamos un caso en el que tenemos una clase que implementa múltiples interfaces con la misma firma de método. ¿Cómo decide la clase a qué método de interfaz llamar??
interface InterfaceA fun funD () interface InterfaceB fun funD ()
Aquí tenemos dos interfaces que tienen un método con la misma firma. financiar()
. Vamos a crear una clase que implemente estas dos interfaces y anule la financiar()
método.
class classA: InterfaceA, InterfaceB override fun funD () super.funD () // Error: Muchos supertipos disponibles, especifique el que quiere decir entre corchetes angulares, por ejemplo, 'súper'
El compilador está confundido acerca de llamar al super.funD ()
Método porque las dos interfaces que implementa la clase tienen la misma firma de método.
Para resolver este problema, envolvemos el nombre de la interfaz a la que queremos llamar el método entre paréntesis angulares.
. (IntelliJ IDEA o Android Studio te darán una pista sobre cómo resolver este problema cuando surja).
class classA: InterfaceA, InterfaceB override fun funD () super.funD ()
Aquí vamos a llamar al financiar()
método de InterfazA
. Problema resuelto!
Se crea una nueva clase (subclase) adquiriendo miembros de una clase existente (superclase) y tal vez redefiniendo su implementación predeterminada. Este mecanismo es conocido como herencia En programación orientada a objetos (OOP). Una de las cosas que hacen que Kotlin sea tan impresionante es que abarca los paradigmas de programación funcional y OOP, todo en un solo lenguaje..
La clase base para todas las clases en Kotlin es Alguna
.
Persona de clase: Cualquiera
los Alguna
tipo es equivalente a la Objeto
tipo que tenemos en Java.
clase abierta pública Cualquiera diversión abierta del operador público es igual a (otra: ¿Cualquiera?): código abierto hash público booleano (): Int pública diversión abierta aString (): cadena
los Alguna
tipo contiene los siguientes miembros: es igual a ()
, código hash()
, y también Encadenar()
métodos (similares a Java).
Nuestras clases no necesitan extender explícitamente este tipo. Si no especifica explícitamente a qué clase se extiende una clase nueva, la clase se extiende Alguna
implícitamente. Por esta razón, normalmente no es necesario incluir : Alguna
en su código, lo hacemos en el código anterior para fines de demostración.
Veamos ahora cómo crear clases en Kotlin con herencia en mente.
clase Estudiante clase GraduateStudent: Student ()
En el código de arriba, el Estudiante graduado
clase extiende la superclase Estudiante
. Pero este código no compilará. ¿Por qué? Porque las clases y los métodos son final
por defecto en Kotlin. En otras palabras, no se pueden extender de forma predeterminada, a diferencia de Java, donde las clases y los métodos están abiertos de forma predeterminada.
La mejor práctica de ingeniería de software recomienda que comience a hacer sus clases y métodos. final
por defecto-es decir. si no están específicamente destinados a ser redefinidos o anulados en subclases. El equipo de Kotlin (JetBrains) aplicó esta filosofía de codificación y muchas otras mejores prácticas de desarrollo en el desarrollo de este lenguaje moderno..
Para permitir que se creen subclases a partir de una superclase, tenemos que marcar explícitamente la superclase con la abierto
modificador Este modificador también se aplica a cualquier propiedad o método de superclase que debe ser reemplazado por las subclases.
clase abierta estudiante
Simplemente ponemos el abierto
modificador antes de la clase
palabra clave. Ahora hemos ordenado al compilador que permita a nuestros Estudiante
clase para estar abierto por extensión.
Como se indicó anteriormente, los miembros de una clase de Kotlin también son finales de forma predeterminada.
clase abierta Estudiante open fun schoolFees (): BigDecimal // hacer implementación
En el código anterior, marcamos el pagos escolares
funcionan como abierto
-para que las subclases puedan anularlo.
clase abierta GraduateStudent: Student () override fun schoolFees (): BigDecimal return super.schoolFees () + calculaSchoolFees () private fun calculaSchoolFees (): BigDecimal // calcula y devuelve las cuotas escolares
Aquí, lo abierto. pagos escolares
función de la superclase Estudiante
es invalidado por el Estudiante graduado
añadiendo la clase anular
modificador antes de la divertido
palabra clave. Tenga en cuenta que si reemplaza a un miembro de una superclase o interfaz, el miembro que lo reemplaza también será abierto
por defecto, como en el siguiente ejemplo:
clase ComputerScienceStudent: GraduateStudent () override fun schoolFees (): BigDecimal return super.schoolFees () + calculaSchoolFess () diversión privada calculaSchoolFess (): BigDecimal // calcular y devolver las tarifas escolares
Aunque no marcamos el pagos escolares()
método en el Estudiante graduado
clase con el abierto
modificador, todavía podemos anularlo, como hicimos en el ComputerCienciaStudent
clase. Para que podamos evitar esto, tenemos que marcar el miembro principal como final
.
Recuerde que podemos agregar nueva funcionalidad a una clase, incluso si es definitiva, mediante el uso de funciones de extensión en Kotlin. Para obtener una actualización de las funciones de extensión, echa un vistazo a mis funciones avanzadas en la publicación Kotlin. Además, si necesita una actualización sobre cómo dar a una clase final incluso nuevas propiedades sin heredarlas, lea la sección sobre Propiedades de extensión en mis Propiedades avanzadas y en la publicación de Clases..
Si nuestra superclase tiene un constructor primario como este:
clase abierta Estudiante (nombre de pila val: cadena, apellido de val: cadena) //…
Entonces, cualquier subclase tiene que llamar al constructor principal de la superclase.
clase abierta GraduateStudent (firstName: String, lastName: String): Student (firstName, lastName) //…
Podemos simplemente crear un objeto de la Estudiante graduado
clase como de costumbre:
val graduateStudent = GraduateStudent ("Jon", "Snow") println (graduateStudent.firstName) // Jon
Si la subclase quiere llamar al constructor de superclase desde su constructor secundario, usamos el súper
palabra clave (similar a cómo se invocan los constructores de superclase en Java).
clase abierta GraduateStudent: Student // ... private var thesis: String = "" constructor (firstName: String, LastName: String, thesis: String): super (firstName, lastName) this.thesis = thesis
Si necesita una actualización sobre los constructores de clases en Kotlin, visite la publicación de Mis clases y objetos.
Otra cosa increíble que podemos hacer en Kotlin es darle un alias a un tipo..
Veamos un ejemplo.
persona de la clase de datos (primer nombre de val: String, apellido de val: String, edad val: Int)
En la clase anterior, podemos asignar el Cuerda
y En t
tipos para el Persona
propiedades de alias usando el tipografías
Modificador en Kotlin. Este modificador se utiliza para crear un alias de cualquier tipo en Kotlin, incluidos los que ha creado..
typealias Name = String typealias Age = Int clase de datos Person (val firstName: Name, val lastName: Name, val age: Age)
Como puedes ver, hemos creado un alias. Nombre
y Años
tanto para el Cuerda
y En t
tipos respectivamente. Ahora hemos reemplazado el nombre de pila
y apellido
tipo de propiedad a nuestro alias Nombre
-y también En t
escriba a Años
alias. Tenga en cuenta que no creamos ningún tipo nuevo, sino que creamos un alias para los tipos.
Estos pueden ser útiles cuando desea proporcionar un mejor significado o semántico a los tipos en su base de código de Kotlin. Así que úsalos sabiamente!
En este tutorial, aprendiste más sobre la programación orientada a objetos en Kotlin. Cubrimos lo siguiente:
Si ha estado aprendiendo Kotlin a través de nuestra serie Kotlin From Scratch, asegúrese de haber estado escribiendo el código que ve y ejecutándolo en su IDE. Un gran consejo para entender realmente un nuevo lenguaje de programación (o cualquier concepto de programación) que esté aprendiendo es asegurarse de no solo leer el recurso o la guía de aprendizaje, sino también escribir el código real y ejecutarlo.!
En el siguiente tutorial de la serie Kotlin From Scratch, se le presentará el manejo de excepciones en Kotlin. Te veo pronto!
Para obtener más información sobre el idioma Kotlin, recomiendo visitar la documentación de Kotlin. O echa un vistazo a algunas de nuestras otras publicaciones de desarrollo de aplicaciones para Android aquí en Envato Tuts!