Classes de données en Kotlin

Classes de données en Kotlin

1. Vue d'ensemble

Le langage Kotlin introduit le concept de classes de données, qui représentent des classes simples utilisées en tant que conteneurs de données et n'encapsulent aucune logique supplémentaire. En termes simples, la solution de Kotlin nous permet d’éviter d’écrire beaucoup de code standard.

Dans cet article rapide, nous allons examiner les classes de données dans Kotlin et les comparer avec leurs homologues Java.

2. Configuration de Kotlin

Pour commencer à configurer le projet Kotlin, consultez notre tutorielintroduction to the Kotlin Language.

3. Classes de données en Java

Si nous voulions créer une entréeMovie en Java, nous aurions besoin d'écrire beaucoup de code standard:

public class Movie {

    private String name;
    private String studio;
    private float rating;

    public Movie(String name, String studio, float rating) {
        this.name = name;
        this.studio = studio;
        this.rating = rating;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getStudio() {
        return studio;
    }

    public void setStudio(String studio) {
        this.studio = studio;
    }

    public float getRating() {
        return rating;
    }

    public void setRating(float rating) {
        this.rating = rating;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;

        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result + Float.floatToIntBits(rating);
        result = prime * result + ((studio == null) ? 0 : studio.hashCode());

        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;

        if (obj == null)
            return false;

        if (getClass() != obj.getClass())
            return false;

        Movie other = (Movie) obj;

        if (name == null) {
            if (other.name != null)
                return false;

        } else if (!name.equals(other.name))
            return false;

        if (Float.floatToIntBits(rating) != Float.floatToIntBits(other.rating))
            return false;

        if (studio == null) {
            if (other.studio != null)
                return false;

        } else if (!studio.equals(other.studio))
            return false;

        return true;
    }

    @Override
    public String toString() {
        return "Movie [name=" + name + ", studio=" + studio + ", rating=" + rating + "]";
    }
}

86 lignes de code. C’est beaucoup de ne stocker que trois champs dans une classe simple.

4. Classe de données Kotlin

Maintenant, nous allons créerthe same Movie class, with the same functionalities, using Kotlin:

data class Movie(var name: String, var studio: String, var rating: Float)

Comme nous pouvons le voir, c’est beaucoup plus facile et plus propre. Le constructeur,toString(), equals(), hashCode(), et les fonctions supplémentairescopy() etcomponentN() sont générés automatiquement.

4.1. Usage

Une classe de données est instanciée de la même manière que les autres classes:

val movie = Movie("Whiplash", "Sony Pictures", 8.5F)

Maintenant, les propriétés et fonctions de sont disponibles:

println(movie.name)   //Whiplash
println(movie.studio) //Sony Pictures
println(movie.rating) //8.5

movie.rating = 9F

println(movie.toString()) //Movie(name=Whiplash, studio=Sony Pictures, rating=9.0)

4.2. Fonction de copie

La fonctioncopy() est créée, au cas où nous aurions besoin de copier un objet en modifiant certaines de ses propriétés mais en gardant le reste inchangé.

val betterRating = movie.copy(rating = 9.5F)
println(betterRating.toString()) // Movie(name=Whiplash, studio=Sony Pictures, rating=9.5)

Java ne fournit pas de méthode native claire pour copier / cloner des objets. Nous pourrions utiliser l'interfaceClonable,SerializationUtils.clone() ou acloning constructor.

4.3. Déclarations de destruction

Les déclarations de destruction nous permettent de traiter les propriétés des objets comme des valeurs individuelles. Pour chaque propriété de la classe de données out, uncomponentN() est généré:

movie.component1() // name
movie.component2() // studio
movie.component3() // rating

Nous pouvons également créer plusieurs variables à partir de l’objet ou directement à partir d’une fonction. Il est important de ne pas oublier d’utiliser des crochets:

val(name, studio, rating) = movie

fun getMovieInfo() = movie
val(namef, studiof, ratingf) = getMovieInfo()

4.4. Exigences relatives aux classes de données

Pour créer une classe de données, nous devons remplir les conditions suivantes:

  • Le constructeur principal doit avoir au moins un paramètre

  • Tous les paramètres du constructeur principal doivent être marqués commeval ouvar

  • Les classes de données ne peuvent pas être abstraites, ouvertes, scellées ou internes

  • (avant 1.1.) Les classes de données ne peuvent implémenter que des interfaces

Depuis 1.1, les classes de données peuvent étendre d'autres classes.

Si la classe générée doit avoir un constructeur sans paramètre, les valeurs par défaut de toutes les propriétés doivent être spécifiées:

data class Movie(var name: String = "", var studio: String = "", var rating: Float = 0F)

5. Conclusion

Nous avons vu les classes de données dans Kotlin, leur utilisation et leurs exigences, la quantité réduite de code standard écrit et des comparaisons avec le même code en Java.

Si vous voulez en savoir plus sur Kotlin, consultez des articles tels queKotlin Java Interoperability et lesIntroduction to the Kotlin Language déjà mentionnés.

L'implémentation complète de ces exemples peut être trouvée dans nosGitHub project.