簡體   English   中英

Kotlin 中類和對象的區別

[英]Difference between a class and object in Kotlin

我是 Kotlin 的新手,最近將一個簡單的文件從 Java 轉換為 Kotlin。 我想知道為什么 Android 轉換器將我的 java 類更改為 Kotlin 對象。

爪哇:

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:

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

為什么不是:

class MyClass {
    ... etc ...
}

任何幫助將不勝感激,謝謝。

Kotlin關於這方面的文檔非常好,所以請隨意閱讀。

為這個問題選擇的答案在解釋上有一些不好的措辭,很容易誤導人們。 例如,一個對象本身並不是“靜態類”,而是a static instance of a class that there is only one of ,也稱為單例。

或許顯示差異的最好方法是查看 Java 形式的反編譯 Kotlin 代碼。

Kotlin 對象和類:

object ExampleObject {
  fun example() {
  }
}

class ExampleClass {
  fun example() {
  }
}

為了使用ExampleClass ,您需要創建它的一個實例: ExampleClass().example() ,但是對於一個對象,Kotlin 會為您創建它的一個實例,並且您永遠不會調用它的構造函數,而是您只需使用名稱訪問它的靜態實例: ExampleObject.example()

Kotlin 會生成等價的 Java 代碼:

Kotlin 編譯為 Java 字節碼,但是如果我們將上面編譯的 Kotlin 代碼反向編譯為 Java 代碼,我們會得到:

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

您可以通過以下方式在 Kotlin 中使用該對象:

ExampleObject.example()

這將編譯為等效的 Java 字節碼:

ExampleObject.INSTANCE.example()

Kotlin 為什么要引入object

Kotlin 中object的主要用例是因為 Kotlin 試圖取消靜態和原語,給我們留下一種純粹的面向對象語言。 Kotlin 仍然在幕后使用static和原語,但它不鼓勵開發人員再使用這些概念。 相反,現在 Kotlin 用單例對象實例替換了靜態。 以前在 Java 中使用靜態字段的地方,在 Kotlin 中,您現在將創建一個object ,並將該字段放入object

與 Java 的互操作性:

由於 Kotlin 與 Java 100% 可互操作,因此有時您會希望以更便於 Java 閱讀的方式公開某些 API 或字段。 為此,您可以使用@JvmStatic注釋。 通過注釋字段或一個函數object@JvmStatic ,它將編譯到靜態字段的Java可以使用更方便。

伴生對象:

值得一提的最后一件事是companion object 在 Java 中,您的類通常包含一些靜態內容,但也包含一些非靜態/實例內容。 科特林允許你做伴侶的對象,這是類似的object š綁在class ,這意味着一個類可以訪問它的同伴對象的私有函數和屬性:

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

Kotlin 對象就像一個無法實例化的類,因此必須按名稱調用它。 (一個靜態類本身)

android 轉換器看到您的類僅包含一個靜態方法,因此將其轉換為 Kotlin 對象。

在此處閱讀更多相關信息: http : //petersommerhoff.com/dev/kotlin/kotlin-for-java-devs/#objects

一個對象是一個單例。 您無需創建實例即可使用它。

需要實例化一個類才能使用

就像在 Java 中你可以說 Math.sqrt(2) 一樣,你不需要創建一個 Math 實例來使用 sqrt,在 Kotlin 中你可以創建一個對象來保存這些方法,它們實際上是靜態的。

這里有一些信息:

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

IntelliJ 顯然足夠聰明,可以檢測到您需要一個對象,因為您只有靜態 Java 方法。

之間的區別:對象|| || 伴生對象|| 數據類

1.對象

  • 對象聲明在第一次訪問時被延遲初始化。
  • 對象就像單例類
  • 整個應用程序只有一個參考
  • 訪問成員、方法,無需創建實例

2.班級

  • 您可以創建多個參考
  • 需要為訪問成員、方法創建實例

3.伴侶對象

  • 當加載相應的類時初始化一個伴生對象
  • 默認情況下,在object MyClass{} ,整個變量具有單一引用,但在companion object您可以選擇創建靜態方法或創建靜態變量
  • 您可以創建單例類

4.數據類

  • 用於保存數據/狀態的類
  • Kotlin 的數據類,你不需要自己編寫/生成所有冗長的樣板代碼
  • 編譯器自動為所有可變屬性生成默認的 getter 和 setter
  • 編譯器自動導出標准方法的實現,如equals()hashCode()toString()

例子

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

您也可以在沒有對象聲明的情況下定義函數。 只是在 .kt 文件中例如:

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

這個函數與聲明 .kt 文件的包有關。 你可以在這里閱讀更多關於它的信息https://kotlinlang.org/docs/reference/packages.html

基於@speirce7 的回答:

以下代碼顯示了 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.
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM