Kotlin中的类和对象之间的区别


101

我是Kotlin的新手,最近将一个简单文件从Java转换为Kotlin。我想知道为什么Android转换器将我的java类更改为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:

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

任何帮助将不胜感激谢谢。

Answers:



168

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

等效的Java代码Kotlin将生成:

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为什么引入objects?

object在Kotlin中主要的用例是因为Kotlin试图消除静态和基元,而给我们留下了纯粹的面向对象的语言。Kotlin仍然static在引擎盖下使用和原始语言,但它不鼓励开发人员再使用这些概念。相反,现在Kotlin用单例对象实例替换了static。在Java中以前使用静态字段的地方,现在您将在Kotlin中创建一个object,并将该字段放在中object

与Java的互操作性:

因为Kotlin可与Java 100%互操作,所以有时您会希望以更好的Java方式公开某些API或字段。为此,您可以使用@JvmStatic注释。通过object用with 注释字段或函数@JvmStatic,它将编译为Java可以更轻松使用的静态字段。

随播对象:

值得一提的最后一件事是companion objects。在Java中,通常您的类具有一些静态内容,但也具有一些非静态/实例内容。Kotlin允许您对伴随对象进行类似的操作,这些对象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)
  }
}

6
很好的解释。非常感谢。
丹麦的Ansari,

12

一个对象是一个单例。您无需创建实例即可使用它。

需要实例化一个类才能使用

与在Java中可以说Math.sqrt(2)的方式相同,无需创建使用Math sqrt的Math实例,在Kotlin中,您可以创建一个对象来容纳这些方法,并且它们实际上是静态的。

这里有一些信息:

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

IntelliJ显然已经足够聪明,可以检测到您需要一个对象,因为您只有静态的Java方法。


等一下,但是如果我的班级Human有一个静态的int字段Population,那么在Kotlin中会是什么样子?companion object { @JvmField val Population; }或者其他的东西?
Squirrelkiller


1

建立在@ 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.
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.