Différence entre une classe et un objet dans Kotlin

99

Je suis nouveau sur Kotlin et j'ai récemment converti un simple fichier de java en 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;
    }
}

Kotlin converti:

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 n'était-ce pas:

class MyClass {
    ... etc ...
}

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

Croquant234
la source

Réponses:

96

Un objet Kotlin est comme une classe qui ne peut pas être instanciée, il doit donc être appelé par son nom. (une classe statique en soi)

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

En savoir plus à ce sujet ici: http://petersommerhoff.com/dev/kotlin/kotlin-for-java-devs/#objects

Gros titre
la source
166

La documentation de Kotlin à ce sujet est plutôt bonne, alors n'hésitez pas à la lire.

La réponse choisie pour cette question a 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 plutôt il est a static instance of a class that there is only one of, autrement connu comme 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() {
  }
}

Pour utiliser le ExampleClass, vous devez en créer une instance:, ExampleClass().example()mais avec un objet, Kotlin en crée une seule instance pour vous, et vous n'appelez jamais son constructeur, vous accédez simplement à son instance statique en utilisant le nom: ExampleObject.example().

Le code Java équivalent que Kotlin générerait:

Kotlin compile en code octet Java, mais si nous compilons à l'inverse le 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 utiliseriez l'objet dans Kotlin de la manière suivante:

ExampleObject.example()

Ce qui compilerait le code d'octet Java équivalent pour:

ExampleObject.INSTANCE.example()

Pourquoi Kotlin introduit-il objects?

Le cas d'utilisation principal de objectdans Kotlin est que Kotlin essaie de se débarrasser de la statique et des primitives, nous laissant avec un langage purement orienté objet. Kotlin utilise toujours des staticprimitives sous le capot, mais il décourage les développeurs d'utiliser plus ces concepts. Au lieu de cela, Kotlin remplace désormais statique par des instances d'objet singleton. Là où vous utilisiez auparavant un champ statique en Java, dans Kotlin, vous allez maintenant créer un objectchamp et le mettre dans le fichier object.

Interopérabilité avec Java:

Comme 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 l' @JvmStaticannotation. En annotant un champ ou une fonction dans un objectavec @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 l' companion objectart. En Java, vous avez généralement des classes qui ont du contenu statique, mais aussi du contenu non statique / d'instance. Kotlin vous permet de faire quelque chose de similaire avec les objets compagnons, qui sont objectliés à a class, ce qui signifie qu'une classe peut accéder aux fonctions et propriétés privées de son objet 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)
  }
}
spierce7
la source
6
Belle explication. Merci beaucoup.
Danish Ansari
12

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, dans 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 évidemment été suffisamment intelligent pour détecter que vous avez besoin d'un objet puisque vous n'avez que des méthodes java statiques.

Bruce Lowe
la source
Attendez mais si ma classe Humana un champ int statique Population, à quoi cela ressemblerait-il dans Kotlin? companion object { @JvmField val Population; }ou quelque chose?
Squirrelkiller
3

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

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

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

Silvestr
la source
1

S'appuyant sur la réponse de @ speirce7:

Le code suivant montre la différence fondamentale entre une classe et un objet en ce qui concerne 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.
}
Raj
la source