Perbedaan antara kelas dan objek di Kotlin

101

Saya baru mengenal Kotlin dan baru-baru ini mengonversi file sederhana dari java ke Kotlin. Saya bertanya-tanya mengapa konverter Android mengubah kelas java saya menjadi objek Kotlin.

Jawa:

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 yang Dikonversi:

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
    }
}

Kenapa tidak:

class MyClass {
    ... etc ...
}

Bantuan apa pun akan sangat dihargai, terima kasih.

Renyah 234
sumber

Jawaban:

168

Dokumentasi Kotlin tentang ini cukup bagus, jadi silakan membacanya.

Jawaban yang dipilih untuk pertanyaan ini memiliki penjelasan fraseologi yang buruk, dan dapat dengan mudah menyesatkan orang. Misalnya, sebuah objek bukanlah "kelas statis per se", melainkan a static instance of a class that there is only one of, atau dikenal sebagai singleton.

Mungkin cara terbaik untuk menunjukkan perbedaannya adalah dengan melihat kode Kotlin yang telah didekompilasi dalam bentuk Java.

Objek dan kelas Kotlin:

object ExampleObject {
  fun example() {
  }
}

class ExampleClass {
  fun example() {
  }
}

Untuk menggunakan ExampleClass, Anda perlu membuat instance-nya ExampleClass().example():, tetapi dengan sebuah objek, Kotlin membuat satu instance untuk Anda, dan Anda tidak pernah memanggilnya konstruktor, Anda cukup mengakses instance statisnya dengan menggunakan nama: ExampleObject.example().

Kode Java setara yang akan dihasilkan Kotlin:

Kotlin mengkompilasi ke kode byte Java, tetapi jika kita mengkompilasi terbalik kode Kotlin yang dikompilasi di atas ke kode Java, inilah yang kita dapatkan:

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() {
   }
}

Anda akan menggunakan objek di Kotlin dengan cara berikut:

ExampleObject.example()

Yang akan dikompilasi ke kode byte Java yang setara untuk:

ExampleObject.INSTANCE.example()

Mengapa Kotlin memperkenalkan objects?

Kasus penggunaan utama objectdi Kotlin adalah karena Kotlin mencoba menghilangkan statis, dan primitif, meninggalkan kita dengan bahasa berorientasi objek murni. Kotlin masih menggunakan staticdan primitif di balik kap mesin, tetapi hal itu membuat pengembang enggan menggunakan konsep itu lagi. Sebagai gantinya, sekarang Kotlin mengganti statis dengan instance objek tunggal. Di mana Anda sebelumnya akan menggunakan bidang statis di Java, di Kotlin Anda sekarang akan membuat object, dan meletakkan bidang itu di object.

Interoperabilitas dengan Java:

Karena Kotlin 100% dapat dioperasikan dengan Java, terkadang Anda ingin mengekspos API atau kolom tertentu dengan cara yang lebih baik untuk dibaca oleh Java. Untuk melakukan ini, Anda dapat menggunakan @JvmStaticanotasi. Dengan menganotasi bidang atau fungsi dalam objectdengan @JvmStatic, itu akan mengkompilasi ke bidang statis yang dapat digunakan Java dengan lebih mudah.

Objek Pendamping:

Satu hal terakhir yang perlu disebutkan adalah companion objects. Di Java, Anda biasanya memiliki kelas yang memiliki beberapa konten statis, tetapi juga beberapa konten non-statis / instance. Kotlin memungkinkan Anda melakukan sesuatu yang serupa dengan objek pendamping, yang objectterikat ke sebuah class, yang berarti kelas dapat mengakses fungsi dan properti pribadi objek pendampingnya:

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
sumber
6
Penjelasan yang bagus. Terima kasih banyak.
Danish Ansari
12

Objek adalah singleton. Anda tidak perlu membuat instance untuk menggunakannya.

Sebuah kelas perlu dibuat instance-nya untuk digunakan

Dengan cara yang sama seperti di Java, Anda dapat mengatakan Math.sqrt (2) dan Anda tidak perlu membuat instance Math untuk menggunakan sqrt, di Kotlin Anda dapat membuat objek untuk menampung metode ini, dan secara efektif bersifat statis.

Ada beberapa info disini:

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

IntelliJ jelas sudah cukup pintar untuk mendeteksi Anda memerlukan objek karena Anda hanya memiliki metode java statis.

Bruce Lowe
sumber
Tunggu, tetapi jika kelas saya Humanmemiliki kolom int statis Population, bagaimana tampilannya di Kotlin? companion object { @JvmField val Population; }atau sesuatu?
Squirrelkiller
3

Anda juga bisa mendefinisikan fungsi tanpa deklarasi objek. Hanya di file .kt Misalnya:

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

Dan fungsi ini terkait dengan paket di mana file .kt dideklarasikan. Anda dapat membaca lebih lanjut di sini https://kotlinlang.org/docs/reference/packages.html

Silvestr
sumber
1

Berdasarkan jawaban @ speirce7:

Kode berikut menunjukkan perbedaan mendasar antara Class dan Object saat berhubungan dengan 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
sumber