web-dev-qa-db-fra.com

Différence entre une classe et un objet dans Kotlin

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.

74
Crunchy234

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 constaté que votre classe ne contenait qu'une méthode statique et l'a donc convertie en objet Kotlin.

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

77
Headline

documentation de Kotlin c'est assez bon, alors n'hésitez pas à le lire.

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

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

Voici un objet et une 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 unique pour vous, et vous n’appelez jamais son constructeur. accédez à son instance statique en utilisant le nom: ExampleObject.example().

Voici le code Java équivalent que Kotlin générerait:

Kotlin compile le code en octets 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 jusqu'à l'équivalent Java octet code pour:

ExampleObject.INSTANCE.example()

Pourquoi Kotlin introduit-t-il objects?

Le principal cas d'utilisation de object chez Kotlin est que Kotlin essaie de supprimer les primitives et les statiques, nous laissant ainsi un langage purement orienté objet. Kotlin utilise toujours static et des primitives sous le capot, mais il décourage les développeurs de ne plus utiliser ces concepts. Au lieu de cela, Kotlin remplace désormais static par des instances d'objet singleton. Là où vous utiliseriez auparavant un champ statique en Java, vous créerez maintenant dans Kotlin un object et vous le placerez dans le object.

Interopérabilité avec Java:

Comme Kotlin est 100% interopérable avec Java, vous souhaiterez parfois exposer certaines API ou certains champs de manière plus lisible pour Java. Pour ce faire, vous pouvez utiliser l'annotation @JvmStatic. En annotant un champ ou une fonction dans un object avec @JvmStatic, il sera compilé en champs statiques que Java peut utiliser plus facilement.

Objets associés:

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

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)
  }
}
114
spierce7

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 que dans Java, vous pouvez dire Math.sqrt (2) et que 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. efficacement statique.

Il y a quelques informations ici:

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

IntelliJ a évidemment été assez intelligent pour détecter que vous avez besoin d’un objet car vous n’avez que des méthodes statiques Java.

11
Bruce Lowe

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

3
Silvestr

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.
}
1
Raj