Kotlin'de bir sınıf ve nesne arasındaki fark


107

Kotlin'de yeniyim ve kısa süre önce basit bir dosyayı java'dan Kotlin'e dönüştürdüm. Android dönüştürücünün java sınıfımı bir Kotlin nesnesine neden değiştirdiğini merak ediyorum.

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

Dönüştürülmüş 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
    }
}

Neden değildi:

class MyClass {
    ... etc ...
}

Herhangi bir yardım büyük, teşekkürler duyacağız.

Yanıtlar:


103

Bir Kotlin nesnesi, somutlaştırılamayan bir sınıfa benzer, bu nedenle adıyla çağrılması gerekir. (kendi başına statik bir sınıf)

Android dönüştürücü, sınıfınızın yalnızca statik bir yöntem içerdiğini gördü, bu nedenle onu bir Kotlin nesnesine dönüştürdü.

Buradan daha fazla bilgi edinin: http://petersommerhoff.com/dev/kotlin/kotlin-for-java-devs/#objects


172

Kotlin'in bu konudaki belgeleri oldukça iyi, bu yüzden okumaktan çekinmeyin.

Bu soru için seçilen cevabın açıklamasında bazı zayıf ifadeler vardır ve insanları kolayca yanlış yönlendirebilir. Örneğin, bir nesne "kendi başına statik bir sınıf" değildir a static instance of a class that there is only one of, aksine tekil olarak bilinir.

Belki de farkı göstermenin en iyi yolu, derlenmiş Kotlin koduna Java biçiminde bakmaktır.

Kotlin nesnesi ve sınıfı:

object ExampleObject {
  fun example() {
  }
}

class ExampleClass {
  fun example() {
  }
}

Kullanmak için ExampleClass, bunun bir örneğini oluşturmak için yapmamiz gereken: ExampleClass().example()ama bir nesneyle, Kotlin sizin için tek bir örneğini oluşturur ve hiç yerine sadece kullanarak statik örneği var erişmek, 's yapıcısı demiyorlar isim: ExampleObject.example().

Eşdeğer Java kodu Kotlin şunları üretir:

Kotlin, Java bayt kodunu derler, ancak yukarıdaki derlenmiş Kotlin kodunu Java koduna ters derlersek şunu elde ederiz:

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

Nesneyi Kotlin'de şu şekilde kullanırsınız:

ExampleObject.example()

Aşağıdakiler için eşdeğer Java bayt koduna derlenir:

ExampleObject.INSTANCE.example()

Kotlin neden objects tanıttı ?

objectKotlin'deki birincil kullanım durumu, Kotlin'in statik ve ilkelleri ortadan kaldırmaya çalışması ve bizi tamamen nesneye yönelik bir dil bırakmasıdır. Kotlin hala statickaputun altında ilkelleri kullanıyor , ancak geliştiricileri bu kavramları daha fazla kullanmaya teşvik ediyor. Bunun yerine, Kotlin artık statik yerine tekli nesne örneklerini değiştiriyor. Daha önce Java'da statik alan kullanacağınız yerde, Kotlin'de şimdi bir oluşturacak objectve bu alanı object.

Java ile birlikte çalışabilirlik:

Kotlin, Java ile% 100 birlikte çalışabilir olduğundan, bazen belirli API'leri veya alanları Java'nın okuması için daha hoş bir şekilde ortaya çıkarmak isteyebilirsiniz. Bunu yapmak için @JvmStaticek açıklamayı kullanabilirsiniz . Bir alan veya bir in bir işlevi açıklamalar ekleyerek objectile @JvmStatic, bu Java daha kolay kullanabilirsiniz statik alanlara aşağı derlemek olacaktır.

Tamamlayıcı Nesneler:

Bahsetmeye değer son bir şey companion objects. Java'da, tipik olarak bir miktar statik içeriğe ve aynı zamanda statik olmayan / örnek içeriğe sahip sınıflarınız vardır. Kotlin, a'ya objectbağlı olan tamamlayıcı nesnelerle benzer bir şey yapmanıza izin verir class, yani bir sınıf, eşlik eden nesnenin özel işlevlerine ve özelliklerine erişebilir:

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

6
Güzel açıklama. Çok teşekkürler.
Danish Ansari

12

Bir nesne tekildir. Kullanmak için bir örnek oluşturmanıza gerek yoktur.

Bir sınıfın kullanılması için somutlaştırılması gerekiyor

Java'da Math.sqrt (2) diyebileceğiniz ve sqrt kullanmak için bir Math örneği oluşturmanıza gerek olmadığı gibi, Kotlin'de de bu yöntemleri tutmak için bir nesne oluşturabilirsiniz ve bunlar etkili bir şekilde statiktir.

Burada bazı bilgiler var:

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

IntelliJ, yalnızca statik java yöntemlerine sahip olduğunuzdan, bir nesneye ihtiyacınız olduğunu algılayacak kadar akıllıdır.


Bekle ama sınıfımın Humanstatik bir int alanı varsa Population, bu Kotlin'de nasıl görünür? companion object { @JvmField val Population; }ya da başka birşey?
Sincap

4

Ayrıca, nesne bildirimi olmadan işlevleri tanımlayabilirsiniz. Sadece .kt dosyasında Örneğin:

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

Ve bu işlev, .kt dosyasının bildirildiği paketle ilgiliydi. Bununla ilgili daha fazla bilgiyi burada https://kotlinlang.org/docs/reference/packages.html okuyabilirsiniz.


1

@ Speirce7'nin cevabına dayanarak:

Aşağıdaki kod, Kotlin söz konusu olduğunda bir Sınıf ve Nesne arasındaki temel farkı gösterir:

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.
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.