Herencia de Kotlin (con ejemplos)

En este artículo, aprenderá sobre la herencia. Más específicamente, qué es la herencia y cómo implementarla en Kotlin (con la ayuda de ejemplos).

La herencia es una de las características clave de la programación orientada a objetos. Permite al usuario crear una nueva clase (clase derivada) a partir de una clase existente (clase base).

La clase derivada hereda todas las características de la clase base y puede tener características adicionales propias.

Antes de entrar en detalles sobre la herencia de Kotlin, le recomendamos que consulte estos dos artículos:

  • Objetos y clase de Kotlin
  • Constructor principal de Kotlin

¿Por qué la herencia?

Suponga que en su solicitud desea tres personajes: un profesor de matemáticas , un futbolista y un empresario .

Dado que todos los personajes son personas, pueden caminar y hablar. Sin embargo, también tienen algunas habilidades especiales. Un profesor de matemáticas puede enseñar matemáticas , un futbolista puede jugar al fútbol y un empresario puede dirigir un negocio .

Puede crear individualmente tres clases que puedan caminar, hablar y realizar su habilidad especial.

En cada una de las clases, estaría copiando el mismo código para caminar y hablar para cada personaje.

Si desea agregar una nueva característica, comer, debe implementar el mismo código para cada carácter. Esto puede volverse fácilmente propenso a errores (al copiar) y códigos duplicados.

Sería mucho más fácil si tuviéramos una Personclase con características básicas como hablar, caminar, comer, dormir y agregar habilidades especiales a esas características según nuestros personajes. Esto se hace mediante herencia.

El uso de la herencia, ahora no aplicar el mismo código para walk(), talk()y eat()para cada clase. Solo necesitas heredarlos .

Entonces, para MathTeacher(clase derivada), hereda todas las características de una Person(clase base) y agrega una nueva característica teachMath(). Del mismo modo, para la Footballerclase, hereda todas las características de la Personclase y agrega una nueva característica playFootball()y así sucesivamente.

Esto hace que su código sea más limpio, comprensible y ampliable.

Es importante recordar: cuando se trabaja con herencia, cada clase derivada debe satisfacer la condición de si "es" una clase base o no. En el ejemplo anterior, MathTeacher es a Person , Footballer es a Person . No puedes tener algo como, Businessman es un Business .

Herencia de Kotlin

Intentemos implementar la discusión anterior en el código:

 clase abierta Person (edad: Int) (// código para comer, hablar, caminar) clase MathTeacher (edad: Int): Persona (edad) (// otras características del profesor de matemáticas) clase Futbolista (edad: Int): Persona ( edad) (// otras características del futbolista) clase Hombre de negocios (edad: Int): Persona (edad) (// otras características del empresario)

Aquí, Persones una clase base, y las clases MathTeacher, Footballery Businessmanse derivan de la clase de la persona.

Aviso, la palabra clave openantes de la clase base, Person. Es importante.

Por defecto, las clases en Kotlin son definitivas. Si está familiarizado con Java, sabrá que una clase final no puede ser subclasificada. Al usar la anotación abierta en una clase, el compilador le permite derivar nuevas clases de ella.

Ejemplo: herencia de Kotlin

 open class Person(age: Int, name: String) ( init ( println("My name is $name.") println("My age is $age") ) ) class MathTeacher(age: Int, name: String): Person(age, name) ( fun teachMaths() ( println("I teach in primary school.") ) ) class Footballer(age: Int, name: String): Person(age, name) ( fun playFootball() ( println("I play for LA Galaxy.") ) ) fun main(args: Array) ( val t1 = MathTeacher(25, "Jack") t1.teachMaths() println() val f1 = Footballer(29, "Christiano") f1.playFootball() )

Cuando ejecute el programa, la salida será:

Mi nombre es Jack. Mi edad es de 25 años y enseño en la escuela primaria. Mi nombre es Cristiano. Tengo 29 años y juego para LA Galaxy.

Aquí, dos clases MathTeachery Footballerse derivan de la Personclase.

El constructor principal de la Personclase declaró dos propiedades: edad y nombre, y tiene un bloque inicializador. Los Personobjetos de las clases derivadas ( MathTeachery Footballer) pueden acceder al bloque de inicio (y funciones miembro) de la clase base .

Las clases derivadas MathTeachery Footballertienen sus propias funciones miembro teachMaths()y playFootball()respectivamente. Estas funciones son accesibles solo desde los objetos de su clase respectiva.

Cuando MathTeacherse crea el objeto t1 de clase,

 val t1 = MathTeacher (25, "Jack")

Los parámetros se pasan al constructor principal. En Kotlin, el initbloque se llama cuando se crea el objeto. Dado que, MathTeacherse deriva de la Personclase, busca el bloque inicializador en la clase base (Persona) y lo ejecuta. Si el MathTeacherbloque init tuviera, el compilador también habría ejecutado el bloque init de la clase derivada.

A continuación, la teachMaths()función para el objeto t1se llama using t1.teachMaths()statement.

El programa funciona de manera similar cuando se crea un objeto f1de Footballerclase. Ejecuta el bloque init de la clase base. Entonces, el playFootball()método de Footballerclase se llama using statement f1.playFootball().

Notas importantes: herencia de Kotlin

  • Si la clase tiene un constructor primario, la base debe inicializarse usando los parámetros del constructor primario. En el programa anterior, ambas clases derivadas tienen dos parámetros agey name, y ambos parámetros se inicializan en el constructor primario en la clase base.
    Aquí hay otro ejemplo:
     open class Person(age: Int, name: String) ( // some code ) class Footballer(age: Int, name: String, club: String): Person(age, name) ( init ( println("Football player $name of age $age and plays for $club.") ) fun playFootball() ( println("I am playing football.") ) ) fun main(args: Array) ( val f1 = Footballer(29, "Cristiano", "LA Galaxy") )  
    Aquí, el constructor principal de la clase derivada tiene 3 parámetros y la clase base tiene 2 parámetros. Tenga en cuenta que se inicializan ambos parámetros de la clase base.
  • En caso de que no haya un constructor principal, cada clase base tiene que inicializar la base (usando super palabra clave), o delegar a otro constructor que lo haga. Por ejemplo,
     fun main(args: Array) ( val p1 = AuthLog("Bad Password") ) open class Log ( var data: String = "" var numberOfData = 0 constructor(_data: String) ( ) constructor(_data: String, _numberOfData: Int) ( data = _data numberOfData = _numberOfData println("$data: $numberOfData times") ) ) 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, visite Kotlin Secondary Constructor.

Anulación de funciones y propiedades de miembros

If the base class and the derived class contains a member function (or property) with the same name, you can need to override the member function of the derived class using override keyword, and use open keyword for the member function of the base class.

Example: Overriding Member Function

 // Empty primary constructor open class Person() ( open fun displayAge(age: Int) ( println("My age is $age.") ) ) class Girl: Person() ( override fun displayAge(age: Int) ( println("My fake age is $(age - 5).") ) ) fun main(args: Array) ( val girl = Girl() girl.displayAge(31) )

When you run the program, the output will be:

 My fake age is 26.

Here, girl.displayAge(31) calls the displayAge() method of the derived class Girl.

You can override property of the base class in similar way.

Visit how Kotlin getters and setters work in Kotlin before you check the example below.

 // Empty primary constructor 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) ( val girl = Girl() girl.age = 31 println("My fake age is $(girl.age).") )

When you run the program, the output will be:

 My fake age is 26.

As you can see, we have used override and open keywords for age property in derived class and base class respectively.

Calling Members of Base Class from Derived Class

Puede llamar a funciones (y acceder a propiedades) de la clase base desde una clase derivada usando una superpalabra clave. Así es cómo:

 open class Person() ( open fun displayAge(age: Int) ( println("My actual age is $age.") ) ) class Girl: Person() ( override fun displayAge(age: Int) ( // calling function of base class super.displayAge(age) println("My fake age is $(age - 5).") ) ) fun main(args: Array) ( val girl = Girl() girl.displayAge(31) )

Cuando ejecute el programa, la salida será:

 Mi edad es 31. Mi edad falsa es 26.

Articulos interesantes...