English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Programación orientada a objetos (OOP) de Kotlin
En este artículo, aprenderás sobre la herencia. Más específicamente, qué es la herencia y cómo se implementa en Kotlin utilizando la herencia (a través de ejemplos).
La herencia es una de las funciones clave de la programación orientada a objetos. Permite a los usuarios crear una nueva clase (clase derivada) a partir de una clase existente (clase base).
Las clases derivadas heredan todas las funcionalidades de la clase base y pueden tener otras propias.
¿Por qué la herencia?-supongamos que en tu aplicación necesitas tres rolesmaestro de matemáticas(MathTeacher), unfutbolista(Footballer) y uncomerciante (Businessman).
enseñar matemáticas (teachMath). Dado que todos los roles son personas, pueden caminar y hablar. Pero, también tienen habilidades especiales. El maestro de matemáticas puedefutbolista puedey eljugar al fútbol(playFootball), el comerciante puedeGestionar negocios (runBusiness).
Puedes crear tres clases separadas que puedan caminar, hablar y ejecutar sus habilidades especiales.
En cada clase, copiarás el mismo código de caminar y hablar para cada rol.
Si se desea agregar nuevas características - Para comer (comer), necesitas implementar el mismo código para cada rol. Esto fácilmente puede llevar a errores (al copiar) y código repetido.
Si tenemos una clase Persona con funciones básicas, por ejemplo, caminar, comer, dormir y agregar habilidades especiales según nuestro rol, sería mucho más fácil. Esto se realiza a través de la herencia.
Al usar la herencia, ya no necesitas implementar el código de walk(), talk() y eat() para cada clase. Sólo necesitasHerenciaBasta con eso.
Por lo tanto, para MathTeacher (clase derivada), puedes heredar todas las funcionalidades de Persona (clase base) y agregar una nueva función teachingMath(). Del mismo modo, para Footballer, heredas todas las funcionalidades de la clase Persona y agregas una nueva función playFootball(), y así sucesivamente.
Esto hace que tu código sea más conciso, comprensible y extensible.
Es importante recordar:Al manejar la herencia, cada clase derivada debe cumplir con las condiciones de ser una "clase base" En el ejemplo anterior, MathTeacher es una Persona (persona), Footballer es una Persona (persona). No puedes considerar que "comercio (Comercio) es empresa (Empresa)".
Vamos a intentar implementar en el código lo discutido anteriormente:
open class Persona(age: Int) { //El código para comer, hablar y caminar } class MathTeacher(age: Int): Person(age) { //Otras características del maestro de matemáticas } class Footballer(age: Int): Person(age) { //Otras características del futbolista } class Businessman(age: Int): Person(age) { // Otras características del comerciante }
Aquí, Person es la clase base, mientras que las clases MathTeacher, Footballer y Businessman son derivadas de la clase Person.
Nota, la palabra clave open antes de la clase base Person es muy importante.
Por defecto, las clases en Kotlin son finales. Si estás familiarizado con Java, sabrás que las clases finales no pueden ser derivadas. Al usar la anotación en la clase, el compilador permite derivar nuevas clases de ella.
class Person(age: Int, name: String) { init { println("Mi nombre es $name.") println("Mi edad es $age") } } class MathTeacher(age: Int, name: String): Person(age, name) { fun teachMaths() { println("Trabajo enseñando en la primaria.") } } class Footballer(age: Int, name: String): Person(age, name) { fun playFootball() { println("Juego para el LA Galaxy.") } } fun main(args: Array<String>) { val t1 = MathTeacher(25, "Jack") t1.teachMaths() println() val f1 = Footballer(29, "Christiano") f1.playFootball() }
La salida del programa es:
Mi nombre es Jack. Mi edad es 25 Trabajo enseñando en la primaria. Mi nombre es Cristiano. Mi edad es 29 Juego para el LA Galaxy.
Aquí, se han derivado dos clases, MathTeacher y Footballer, de la clase Person.
El constructor principal de la clase Person declara dos propiedades: age y name, y tiene un bloque de inicialización. Los objetos de las clases derivadas de Person (MathTeacher y Footballer) pueden acceder al bloque de inicialización (y a los métodos miembros) de la clase base.
Las clases derivadas MathTeacher y Footballer tienen sus propios métodos miembros teachMaths() y playFootball(). Estos métodos solo pueden ser accedidos desde los objetos de sus clases respectivas.
cuando se crea el objeto de la clase MathTeacher t1 al inicializar
val t1 = MathTeacher(25, "Jack")
los parámetros se pasarán al constructor principal. En Kotlin, al crear un objeto se llama al bloque init. Dado que MathTeacher se deriva de la clase Person, buscará y ejecutará el bloque init en la clase base (Person). Si MathTeacher tiene un bloque init, el compilador también ejecutará el bloque init de la clase derivada.
a continuación, utiliza t1.teachMaths()1llamando a la función teachMaths() del objeto t
para crear el objeto de la clase f1 al inicializar la clase, el funcionamiento del programa es similar. Ejecuta el bloque init de la clase base. Luego, utiliza la instrucción f1.playFootball() llama al método playFootball() de la clase Footballer.
Si la clase tiene un constructor principal, debe usar los parámetros del constructor principal para inicializar la clase base. En el programa anterior, las dos clases derivadas tienen dos parámetros age y name, y estos dos parámetros se inicializan en el constructor principal de la clase base.
Este es otro ejemplo:
class Person(age: Int, name: String) { // algun código } class Footballer(age: Int, name: String, club: String): Person(age, name) { init { println("El futbolista de $age años, $name, juega para $club.") } fun playFootball() { println("Estoy jugando al fútbol.") } } fun main(args: Array<String>) { val f1 = Footballer(29, "Cristiano", "LA Galaxy") }
Aquí, el constructor principal de la clase derivada tiene3un parámetro, mientras que la clase base tiene2un parámetro. Tenga en cuenta que los dos parámetros de la clase base ya están inicializados.
Si no hay constructor principal, cada clase base debe inicializar la clase base (usando la palabra clave super) o delegar a otro constructor que ejecute esta operación. Por ejemplo
fun main(args: Array<String>) { val p1 = AuthLog("Contraseña incorrecta") } abrir clase Log { var data: String = "" var numberOfData = 0 constructor(_data: String) { } constructor(_data: String, _numberOfData: Int) { data = _data numberOfData = _numberOfData println("$data: $numberOfData veces") } } class AuthLog: Log { constructor(_data: String): this("From AuthLog -> + $_data", 10) { } constructor(_data: String, _numberOfData: Int): super(_data, _numberOfData) { } }
Para obtener más información sobre cómo funciona este programa, visiteConstructor secundario de Kotlin.
Si la clase base y la clase derivada contienen miembros con el mismo nombre (o propiedades), es posible que necesite usar la palabra clave override para sobrescribir el miembro de la clase derivada y usar la palabra clave open para el miembro de la clase base.
// Constructor principal vacío open class Person() { open fun displayAge(age: Int) { println("Mi edad es $age.") } } class Girl: Person() { override fun displayAge(age: Int) {}} println("Mi edad virtual es ${age - 5}.") } } fun main(args: Array<String>) { val girl = Girl() girl.displayAge(31) }
La salida del programa es:
su edad virtual es 26.
Aquí, girl.displayAge(31) Llamar al método displayAge() de la clase derivada Girl.
También puede sobrescribir las propiedades de la clase base de manera similar.
Antes de aprender los siguientes ejemplos, puede visitar Getter y setter en Kotlin Ver cómo funciona.
//Constructor principal vacío open class Person() { open var age: Int = 0 get() = field set(value) { field = value } } class Girl: Person() { override var age: Int = 0 get() = field set(value) { field = value - 5 } } fun main(args: Array<String>) { val girl = Girl() girl.age = 31 println("Mi edad virtual es ${girl.age}.") }
La salida del programa es:
Mi edad virtual es 26.
Como puede ver, hemos utilizado las palabras clave override y open para la propiedad age tanto en la clase derivada como en la clase base.
Puede usar la palabra clave super para llamar a los métodos de la clase base desde la clase derivada (y acceder a las propiedades). Aquí está cómo hacerlo:
open class Person() { open fun displayAge(age: Int) { println("Mi edad real es $age.") } } class Girl: Person() { override fun displayAge(age: Int) {}} //Llamar a la función de la clase base super.displayAge(age) println("Mi edad virtual es ${age - 5}.") } } fun main(args: Array<String>) { val girl = Girl() girl.displayAge(31) }
La salida del programa es:
Mi edad real es 31. Mi edad virtual es 26.