Héritage Kotlin (avec des exemples)

Dans cet article, vous découvrirez l'héritage. Plus précisément, qu'est-ce que l'héritage et comment l'implémenter dans Kotlin (à l'aide d'exemples).

L'héritage est l'une des principales caractéristiques de la programmation orientée objet. Il permet à l'utilisateur de créer une nouvelle classe (classe dérivée) à partir d'une classe existante (classe de base).

La classe dérivée hérite de toutes les fonctionnalités de la classe de base et peut avoir ses propres fonctionnalités supplémentaires.

Avant d'entrer dans les détails sur l'héritage de Kotlin, nous vous recommandons de consulter ces deux articles:

  • Classe et objets Kotlin
  • Constructeur principal Kotlin

Pourquoi l'héritage?

Supposons que, dans votre application, vous vouliez trois personnages: un professeur de mathématiques , un footballeur et un homme d'affaires .

Puisque tous les personnages sont des personnes, ils peuvent marcher et parler. Cependant, ils ont également des compétences spéciales. Un professeur de mathématiques peut enseigner les mathématiques , un footballeur peut jouer au football et un homme d'affaires peut diriger une entreprise .

Vous pouvez créer individuellement trois classes qui peuvent marcher, parler et exécuter leurs compétences spéciales.

Dans chacune des classes, vous copieriez le même code pour marcher et parler pour chaque personnage.

Si vous souhaitez ajouter une nouvelle fonctionnalité - eat, vous devez implémenter le même code pour chaque caractère. Cela peut facilement devenir sujet à des erreurs (lors de la copie) et des codes en double.

Ce serait beaucoup plus facile si nous avions une Personclasse avec des fonctionnalités de base comme parler, marcher, manger, dormir et ajouter des compétences spéciales à ces fonctionnalités selon nos personnages. Cela se fait en utilisant l'héritage.

Utilisation de l' héritage, maintenant , vous ne met pas en œuvre le même code pour walk(), talk()et eat()pour chaque classe. Vous avez juste besoin d'en hériter .

Ainsi, pour MathTeacher(classe dérivée), vous héritez de toutes les fonctionnalités d'une Person(classe de base) et ajoutez une nouvelle fonctionnalité teachMath(). De même, pour la Footballerclasse, vous héritez de toutes les fonctionnalités de la Personclasse et ajoutez une nouvelle fonctionnalité playFootball()et ainsi de suite.

Cela rend votre code plus propre, compréhensible et extensible.

Il est important de se rappeler: Lorsque vous travaillez avec l'héritage, chaque classe dérivée doit satisfaire à la condition qu'elle "soit" une classe de base ou non. Dans l'exemple ci-dessus, MathTeacher est a Person , Footballer est a Person . Vous ne pouvez pas avoir quelque chose comme, Businessman est un Business .

Héritage de Kotlin

Essayons d'implémenter la discussion ci-dessus dans le code:

 classe ouverte Person (age: Int) (// code pour manger, parler, marcher) class MathTeacher (age: Int): Person (age) (// autres caractéristiques du professeur de mathématiques) class Footballer (age: Int): Person ( age) (// autres caractéristiques du footballeur) classe Homme d'affaires (age: Int): Personne (âge) (// autres caractéristiques de l'homme d'affaires)

Ici, Personest une classe de base, et les classes MathTeacher, Footballeret Businessmansont dérivées de la classe Person.

Remarquez, le mot - clé openavant la classe de base, Person. C'est important.

Par défaut, les classes de Kotlin sont finales. Si vous êtes familiarisé avec Java, vous savez qu'une classe finale ne peut pas être sous-classée. En utilisant l'annotation ouverte sur une classe, le compilateur vous permet d'en dériver de nouvelles classes.

Exemple: héritage 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() )

Lorsque vous exécutez le programme, la sortie sera:

Mon nom est Jack. J'ai 25 ans et j'enseigne à l'école primaire. Mon nom est Cristiano. J'ai 29 ans, je joue pour LA Galaxy.

Ici, deux classes MathTeacheret Footballersont dérivées de la Personclasse.

Le constructeur principal de la Personclasse a déclaré deux propriétés: l'âge et le nom, et il a un bloc d'initialisation. Le bloc initiateur (et les fonctions membres) de la classe de base Personsont accessibles par les objets des classes dérivées ( MathTeacheret Footballer).

Les classes dérivées MathTeacheret Footballeront leurs propres fonctions membres teachMaths()et playFootball()respectivement. Ces fonctions ne sont accessibles qu'à partir des objets de leur classe respective.

Lorsque l'objet t1 de MathTeacherclasse est créé,

 val t1 = MathTeacher (25, "Jack")

Les paramètres sont transmis au constructeur principal. Dans Kotlin, le initbloc est appelé lorsque l'objet est créé. Puisque, MathTeacherest dérivé de la Personclasse, il recherche le bloc d'initialisation dans la classe de base (Person) et l'exécute. Si le MathTeacherbloc avait init, le compilateur aurait également exécuté le bloc init de la classe dérivée.

Ensuite, la teachMaths()fonction d'objet t1est appelée using t1.teachMaths()statement.

Le programme fonctionne de manière similaire lorsque l'objet f1de la Footballerclasse est créé. Il exécute le bloc init de la classe de base. Ensuite, la playFootball()méthode de Footballerclasse est appelée using statement f1.playFootball().

Notes importantes: héritage de Kotlin

  • Si la classe a un constructeur principal, la base doit être initialisée à l'aide des paramètres du constructeur principal. Dans le programme ci-dessus, les deux classes dérivées ont deux paramètres ageet name, et ces deux paramètres sont initialisés dans le constructeur principal de la classe de base.
    Voici un autre exemple:
     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") )  
    Ici, le constructeur principal de la classe dérivée a 3 paramètres, et la classe de base a 2 paramètres. Notez que les deux paramètres de la classe de base sont initialisés.
  • En cas d'absence de constructeur principal, chaque classe de base doit initialiser la base (en utilisant le mot clé super), ou déléguer à un autre constructeur qui fait cela. Par exemple,
     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) ( ) )
    Pour en savoir plus sur le fonctionnement de ce programme, visitez Kotlin Secondary Constructor.

Remplacement des fonctions et propriétés des membres

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

Vous pouvez appeler des fonctions (et accéder aux propriétés) de la classe de base à partir d'une classe dérivée à l'aide de supermot-clé. Voici comment:

 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) )

Lorsque vous exécutez le programme, la sortie sera:

 Mon âge est de 31 ans. Mon faux âge est de 26 ans.

Articles intéressants...