Soy nuevo en Kotlin y recientemente convertí un archivo simple de Java a Kotlin. Me pregunto por qué el convertidor de Android cambió mi clase Java a un objeto 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 convertido:
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 } }¿Por qué no fue:
class MyClass { ... etc ... }Cualquier ayuda sería muy apreciada, gracias.
Un objeto de Kotlin es como una clase de la que no se puede crear una instancia, por lo que debe llamarse por su nombre. (una clase estática per se)
El convertidor de Android vio que su clase contenía solo un método estático, por lo que la convirtió en un objeto Kotlin.
Lea más sobre esto aquí: http://petersommerhoff.com/dev/kotlin/kotlin-for-java-devs/#objects
También puede definir funciones sin declaración de objeto. Solo en archivo .kt Por ejemplo:
fun GenerateChecksumCrc16(bytes: ByteArray): Int { ... }Y esta función estaba relacionada con el paquete donde se declara el archivo .kt. Puede leer más sobre esto aquí https://kotlinlang.org/docs/reference/packages.html
Un objeto es un singleton. No necesita crear una instancia para usarlo.
Una clase necesita ser instanciada para ser utilizada
De la misma manera que en Java puedes decir Math.sqrt(2) y no necesitas crear una instancia de Math para usar sqrt, en Kotlin puedes crear un objeto para contener estos métodos, y son efectivamente estáticos.
Hay algo de información aquí:
https://kotlinlang.org/docs/reference/object-declarations.html
Obviamente, IntelliJ ha sido lo suficientemente inteligente como para detectar que necesita un objeto, ya que solo tiene métodos Java estáticos.
Diferente entre: objeto || clase || objeto complementario || clase de datos
object MyClass{} , de forma predeterminada, la variable completa tiene una referencia única, pero en companion object tiene la opción de crear un método estático o crear una variable estáticaequals() , hashCode() y toString()Ejemplos
//---------------1- object ---------------------- object MyClass1 { fun checkData { // ... } } MyClass1.checkData() // call method //----------------2- class --------------------- class MyClass2 { fun checkData { // ... } } var myClass = MyClass2() myClass.checkData() // call method //----------------3- companion object --------------------- class MyClass3 { companion object { fun myStaticMethod() { // ... } } fun myInstanceMethod() { // ... } } MyClass3.myStaticMethod() // call companion object member var myClass = MyClass3() myClass.myInstanceMethod() // call simple method using reference //----------------4- data class --------------------- data class MyClass4(val name: String, val rId: Int)La documentación de Kotlin sobre esto es bastante buena, así que no dudes en leerla.
La respuesta elegida para esta pregunta tiene una fraseología deficiente en su explicación y fácilmente podría inducir a error a las personas. Por ejemplo, un objeto no es "una clase estática per se", sino que es a static instance of a class that there is only one of , también conocida como singleton.
Quizás la mejor manera de mostrar la diferencia es mirar el código Kotlin descompilado en formato Java.
Objeto y clase de Kotlin:
object ExampleObject { fun example() { } } class ExampleClass { fun example() { } } Para usar ExampleClass , debe crear una instancia de él: ExampleClass().example() , pero con un objeto, Kotlin crea una sola instancia para usted, y nunca llama a su constructor, en su lugar simplemente accede a su instancia estática usando el nombre: ExampleObject.example() .
El código Java equivalente que Kotlin generaría:
Kotlin se compila en el código de bytes de Java, pero si hacemos una compilación inversa del código de Kotlin compilado anterior en el código de Java, esto es lo que obtenemos:
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() { } }Usarías el objeto en Kotlin de la siguiente manera:
ExampleObject.example()Lo que compilaría hasta el código de bytes de Java equivalente para:
ExampleObject.INSTANCE.example() ¿Por qué Kotlin introduce object s?
El caso de uso principal de object en Kotlin se debe a que Kotlin trata de eliminar lo estático y lo primitivo, dejándonos con un lenguaje puramente orientado a objetos. Kotlin todavía usa static y primitivos debajo del capó, pero desalienta a los desarrolladores a usar esos conceptos más. En su lugar, ahora Kotlin reemplaza las estáticas con instancias de objetos singleton. Donde anteriormente usaría un campo estático en Java, en Kotlin ahora creará un object y colocará ese campo en el object .
Interoperabilidad con Java:
Debido a que Kotlin es 100% interoperable con Java, a veces querrás exponer ciertas API o campos de una manera que sea más agradable de leer para Java. Para hacer esto, puede usar la anotación @JvmStatic . Al anotar un campo o una función en un object con @JvmStatic , se compilará en campos estáticos que Java puede usar más fácilmente.
Objetos complementarios:
Una última cosa que vale la pena mencionar son los companion object . En Java, normalmente tiene clases que tienen algo de contenido estático, pero también algo de contenido no estático/de instancia. Kotlin te permite hacer algo similar con los objetos complementarios, que son object vinculados a una class , lo que significa que una clase puede acceder a las funciones y propiedades privadas de su objeto complementario:
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) } }Sobre la base de la respuesta de @ speirce7:
El siguiente código muestra la diferencia básica entre una Clase y un Objeto cuando se trata de 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. }