Kotlin中类和对象的区别

wwodge7n  于 2022-11-16  发布在  Kotlin
关注(0)|答案(6)|浏览(188)

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

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

2cmtqfgy

2cmtqfgy1#

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试图废除static和primitive,留给我们一种纯粹的面向对象的语言。Kotlin仍然使用static和primitive,但是它不鼓励开发人员再使用这些概念。相反,现在Kotlin用singleton对象示例代替了static。以前在Java中使用static field,在Kotlin中,您现在将创建一个object,并将该字段放入object中。

与Java的互操作性:

因为Kotlin是100%可与Java互操作的,所以有时候你会希望以一种更好的方式公开某些API或字段,以便Java读取。为此,你可以使用@JvmStatic注解。通过用@JvmStatic注解object中的字段或函数,它将编译成Java可以更容易使用的静态字段。

伴随对象:

最后值得一提的是companion object s。在Java中,类通常有一些静态内容,但也有一些非静态/示例内容。Kotlin允许你对伴随对象做类似的事情,即object s绑定到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)
  }
}
e4eetjau

e4eetjau2#

一个Kotlin对象就像一个类,它不能被示例化,所以它必须通过名字来调用。(一个静态类本身)
android转换器发现您的类只包含一个静态方法,因此将其转换为Kotlin对象。
在此阅读更多信息:http://petersommerhoff.com/dev/kotlin/kotlin-for-java-devs/#objects

u4vypkhs

u4vypkhs3#

不同:对象||类别||伴随对象||数据类

1.对象

  • 对象声明,在第一次访问时被惰性地初始化。
  • 对象的行为类似于单例类
  • 整个应用程序中只有一个引用
  • 访问成员、方法而不创建示例

2.类

  • 可以创建多个引用
  • 需要创建用于访问成员、方法的示例

3.伴随对象

  • 在加载相应的类时初始化伴随对象
  • object MyClass{}中,默认情况下整个变量具有单个引用,但在companion object中,您可以选择创建静态方法或创建静态变量
  • 您可以建立单一类别

4.data

  • 用于保存数据/状态的类
  • 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)
qc6wkl3g

qc6wkl3g4#

一个对象是一个单独的对象。你不需要创建一个示例来使用它。
类需要示例化才能使用
在Java中,您可以使用Math.sqrt(2),而无需创建Math示例来使用sqrt;同样,在Kotlin中,您可以创建一个对象来保存这些方法,它们实际上是静态的。
这里有一些信息:
https://kotlinlang.org/docs/reference/object-declarations.html
IntelliJ显然已经足够聪明,能够检测到您需要一个对象,因为您只有静态java方法。

vxf3dgd4

vxf3dgd45#

你也可以定义没有对象声明的函数。只在.kt文件中。例如:

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

这个函数与声明了.kt文件包有关您可以在这里阅读更多信息https://kotlinlang.org/docs/reference/packages.html

e5njpo68

e5njpo686#

基于@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.
}

相关问题