131 votes

Différence entre une classe et un objet en Kotlin

Je suis nouveau sur Kotlin et j'ai récemment converti un simple fichier de java à Kotlin. Je me demande pourquoi le convertisseur Android a changé ma classe java en un objet Kotlin.

Java :

public class MyClass {
    static public int GenerateChecksumCrc16(byte bytes[]) {

        int crc = 0xFFFF;
        int temp;
        int crc_byte;

        for (byte aByte : bytes) {

            crc_byte = aByte;

            for (int bit_index = 0; bit_index < 8; bit_index++) {

                temp = ((crc >> 15)) ^ ((crc_byte >> 7));

                crc <<= 1;
                crc &= 0xFFFF;

                if (temp > 0) {
                    crc ^= 0x1021;
                    crc &= 0xFFFF;
                }

                crc_byte <<= 1;
                crc_byte &= 0xFF;

            }
        }

        return crc;
    }
}

Conversion de Kotlin :

object MyClass {
    fun GenerateChecksumCrc16(bytes: ByteArray): Int {

        var crc = 0xFFFF
        var temp: Int
        var crc_byte: Int

        for (aByte in bytes) {

            crc_byte = aByte.toInt()

            for (bit_index in 0..7) {

                temp = crc shr 15 xor (crc_byte shr 7)

                crc = crc shl 1
                crc = crc and 0xFFFF

                if (temp > 0) {
                    crc = crc xor 0x1021
                    crc = crc and 0xFFFF
                }

                crc_byte = crc_byte shl 1
                crc_byte = crc_byte and 0xFF

            }
        }

        return crc
    }
}

Pourquoi ça ne l'était pas :

class MyClass {
    ... etc ...
}

Toute aide serait grandement appréciée, merci.

229voto

spierce7 Points 1212

La documentation de Kotlin sur ce sujet est assez bon, alors n'hésitez pas à le lire.

La réponse choisie pour cette question contient une mauvaise phraséologie dans son explication, et pourrait facilement induire les gens en erreur. Par exemple, un objet n'est pas "une classe statique en soi", mais il est plutôt a static instance of a class that there is only one of autrement dit, un singleton.

La meilleure façon de montrer la différence est peut-être de regarder le code Kotlin décompilé sous forme Java.

Objet et classe Kotlin :

object ExampleObject {
  fun example() {
  }
}

class ExampleClass {
  fun example() {
  }
}

Afin d'utiliser le ExampleClass vous devez en créer une instance : ExampleClass().example() Mais avec un objet, Kotlin crée une seule instance de celui-ci pour vous, et vous n'appelez jamais son constructeur, au lieu de cela vous accédez simplement à son instance statique en utilisant le nom : ExampleObject.example() .

Code Java équivalent que Kotlin générerait :

Kotlin se compile en byte code Java, mais si nous effectuons une compilation inverse du code Kotlin compilé ci-dessus en code Java, voici ce que nous obtenons :

public final class ExampleObject {
   public static final ExampleObject INSTANCE = new ExampleObject();

   private ExampleObject() { }

   public final void example() {
   }
}

public final class ExampleClass {
   public final void example() {
   }
}

Vous utiliserez l'objet en Kotlin de la manière suivante :

ExampleObject.example()

Ce qui se compilerait en un code d'octet Java équivalent à :

ExampleObject.INSTANCE.example()

Pourquoi Kotlin introduit-il object s ?

Le principal cas d'utilisation de object en Kotlin, c'est parce que Kotlin essaie de se débarrasser des statiques et des primitives, nous laissant avec un langage purement orienté objet. Kotlin utilise toujours static et des primitives sous le capot, mais cela décourage les développeurs d'utiliser ces concepts. Au lieu de cela, Kotlin remplace désormais les champs statiques par des instances d'objets singletons. Alors qu'auparavant vous utilisiez un champ statique en Java, en Kotlin, vous créerez désormais une instance d'objet object et mettez ce champ dans le object .

Interopérabilité avec Java :

Étant donné que Kotlin est 100% interopérable avec Java, vous voudrez parfois exposer certaines API ou certains champs d'une manière plus agréable à lire pour Java. Pour ce faire, vous pouvez utiliser la fonction @JvmStatic annotation. En annotant un champ ou une fonction dans un fichier object avec @JvmStatic il se compilera en champs statiques que Java pourra utiliser plus facilement.

Objets compagnons :

Une dernière chose qui mérite d'être mentionnée est que companion object s. En Java, vous avez généralement des classes qui ont un contenu statique, mais aussi un contenu non statique ou d'instance. Kotlin vous permet de faire quelque chose de similaire avec les objets compagnons, qui sont object est lié à un class Une classe peut donc accéder aux fonctions et propriétés privées de son compagnon :

class ExampleClass {
  companion object {
    // Things that would be static in Java would go here in Kotlin
    private const val str = "asdf"
  }

  fun example() {
    // I can access private variables in my companion object
    println(str)
  }
}

16 votes

Bonne explication. Merci beaucoup.

0 votes

Oui, c'est pourquoi un "objet compagnon" est appelé un "objet" à l'intérieur d'une classe. Il s'agit en fait d'un singleton à l'intérieur d'une classe.

119voto

Headline Points 965

Un objet Kotlin est comme une classe qui ne peut pas être instanciée et qui doit donc être appelée par son nom. (une classe statique à proprement parler)

Le convertisseur Android a vu que votre classe ne contenait qu'une méthode statique, il l'a donc convertie en objet Kotlin.

Pour en savoir plus, cliquez ici : http://petersommerhoff.com/dev/kotlin/kotlin-for-java-devs/#objects

14voto

Bruce Lowe Points 4003

Un objet est un singleton. Vous n'avez pas besoin de créer une instance pour l'utiliser.

Une classe doit être instanciée pour être utilisée.

De la même manière qu'en Java, vous pouvez dire Math.sqrt(2) et vous n'avez pas besoin de créer une instance Math pour utiliser sqrt, en Kotlin, vous pouvez créer un objet pour contenir ces méthodes, et elles sont effectivement statiques.

Il y a quelques informations ici :

https://kotlinlang.org/docs/reference/object-declarations.html

IntelliJ a manifestement été assez intelligent pour détecter que vous avez besoin d'un objet puisque vous n'avez que des méthodes statiques java.

0 votes

Attends mais si ma classe Human possède un champ statique int Population comment cela pourrait-il ressembler en Kotlin ? companion object { @JvmField val Population; } ou autre ?

4voto

Silvestr Points 474

Vous pouvez également définir des fonctions sans déclaration d'objet. Juste dans le fichier .kt Par exemple :

fun GenerateChecksumCrc16(bytes: ByteArray): Int {
    ...
}

Et cette fonction était liée au paquet où le fichier .kt est déclaré. Vous pouvez en savoir plus à ce sujet ici https://kotlinlang.org/docs/reference/packages.html

2voto

Raj Points 387

Dans le prolongement de la réponse de @speirce7 :

Le code suivant montre la différence fondamentale entre une classe et un objet en Kotlin :

class ExampleClass(){
    fun example(){
            println("I am in the class.")
    }
}

object ExampleObject{
    fun example(){
            println("I am in the object.")
    }
}

fun main(args: Array<String>){
    val exampleClass = ExampleClass() // A class needs to be instantiated.
    exampleClass.example()            // Running the instance of the object.
    ExampleObject.example()           // An object can be thought of as a Singleton and doesn't need any instantiation.
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X