简体   繁体   English

Kotlin 中类和对象的区别

[英]Difference between a class and object in Kotlin

I'm new to Kotlin and have recently converted a simple file from java to Kotlin.我是 Kotlin 的新手,最近将一个简单的文件从 Java 转换为 Kotlin。 I am wondering why the Android converter changed my java class to a Kotlin object.我想知道为什么 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;
    }
}

Converted Kotlin:转换后的 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
    }
}

Why wasn't it:为什么不是:

class MyClass {
    ... etc ...
}

Any help would be greatly appreciated thanks.任何帮助将不胜感激,谢谢。

Kotlin's documentation on this is pretty good, so feel free to read that. Kotlin关于这方面的文档非常好,所以请随意阅读。

The chosen answer for this question has some poor phraseology in its explanation, and could easily mislead people.为这个问题选择的答案在解释上有一些不好的措辞,很容易误导人们。 For instance, an object is not "a static class per se", but rather it is a static instance of a class that there is only one of , otherwise known as a singleton.例如,一个对象本身并不是“静态类”,而是a static instance of a class that there is only one of ,也称为单例。

Perhaps the best way to show the difference is to look at the decompiled Kotlin code in Java form.或许显示差异的最好方法是查看 Java 形式的反编译 Kotlin 代码。

Kotlin object and class: Kotlin 对象和类:

object ExampleObject {
  fun example() {
  }
}

class ExampleClass {
  fun example() {
  }
}

In order to use the ExampleClass , you need to create an instance of it: ExampleClass().example() , but with an object, Kotlin creates a single instance of it for you, and you don't ever call it's constructor, instead you just access it's static instance by using the name: ExampleObject.example() .为了使用ExampleClass ,您需要创建它的一个实例: ExampleClass().example() ,但是对于一个对象,Kotlin 会为您创建它的一个实例,并且您永远不会调用它的构造函数,而是您只需使用名称访问它的静态实例: ExampleObject.example()

Equivalent Java code Kotlin would generate: Kotlin 会生成等价的 Java 代码:

Kotlin compiles to Java byte code, but if we reverse compile the above compiled Kotlin code to Java code this is what we get: 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() {
   }
}

You would use the object in Kotlin the following way:您可以通过以下方式在 Kotlin 中使用该对象:

ExampleObject.example()

Which would compile down to the equivalent Java byte code for:这将编译为等效的 Java 字节码:

ExampleObject.INSTANCE.example()

Why does Kotlin introduce object s? Kotlin 为什么要引入object

The primary use case of object in Kotlin is because Kotlin tries to do away with static, and primitives, leaving us with a purely object oriented language. Kotlin 中object的主要用例是因为 Kotlin 试图取消静态和原语,给我们留下一种纯粹的面向对象语言。 Kotlin still uses static and primitives underneath the hood, but it discourages devs to use those concepts any more. Kotlin 仍然在幕后使用static和原语,但它不鼓励开发人员再使用这些概念。 Instead, now Kotlin replaces static with singleton object instances.相反,现在 Kotlin 用单例对象实例替换了静态。 Where you would previously use static field in Java, in Kotlin you will now create an object , and put that field in the object .以前在 Java 中使用静态字段的地方,在 Kotlin 中,您现在将创建一个object ,并将该字段放入object

Interoperability with Java:与 Java 的互操作性:

Because Kotlin is 100% interoperable with Java, sometimes you will want to expose certain APIs or fields in a way that is nicer for Java to read.由于 Kotlin 与 Java 100% 可互操作,因此有时您会希望以更便于 Java 阅读的方式公开某些 API 或字段。 To do this, you can use the @JvmStatic annotation.为此,您可以使用@JvmStatic注释。 By annotating a field or a function in an object with @JvmStatic , it will compile down to static fields which Java can use easier.通过注释字段或一个函数object@JvmStatic ,它将编译到静态字段的Java可以使用更方便。

Companion Objects:伴生对象:

One last thing that's worth mentioning is companion object s.值得一提的最后一件事是companion object In Java, you typically have classes that have some static content, but also some non-static / instance content.在 Java 中,您的类通常包含一些静态内容,但也包含一些非静态/实例内容。 Kotlin allows you to do something similar with companion objects, which are object s tied to a class , meaning a class can access it's companion object's private functions and properties:科特林允许你做伴侣的对象,这是类似的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)
  }
}

A Kotlin object is like a class that can't be instantiated so it must be called by name. Kotlin 对象就像一个无法实例化的类,因此必须按名称调用它。 (a static class per se) (一个静态类本身)

The android converter saw that your class contained only a static method, so it converted it to a Kotlin object. android 转换器看到您的类仅包含一个静态方法,因此将其转换为 Kotlin 对象。

Read more about it here: http://petersommerhoff.com/dev/kotlin/kotlin-for-java-devs/#objects在此处阅读更多相关信息: http : //petersommerhoff.com/dev/kotlin/kotlin-for-java-devs/#objects

An object is a singleton.一个对象是一个单例。 You do not need to create an instance to use it.您无需创建实例即可使用它。

A class needs to be instantiated to be used需要实例化一个类才能使用

In the same way that in Java you may say Math.sqrt(2) and you dont need to create a Math instance to use sqrt, in Kotlin you can create an object to hold these methods, and they are effectively static.就像在 Java 中你可以说 Math.sqrt(2) 一样,你不需要创建一个 Math 实例来使用 sqrt,在 Kotlin 中你可以创建一个对象来保存这些方法,它们实际上是静态的。

There is some info here:这里有一些信息:

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

IntelliJ has obviously been smart enough to detect you need an object since you only have static java methods. IntelliJ 显然足够聪明,可以检测到您需要一个对象,因为您只有静态 Java 方法。

Different between : object ||之间的区别:对象|| class |||| companion object ||伴生对象|| data class数据类

1.object 1.对象

  • An object declaration, is initialised lazily, when accessed for the first time.对象声明在第一次访问时被延迟初始化。
  • Object is act like singleton class对象就像单例类
  • Only one reference for whole app整个应用程序只有一个参考
  • Access members, methods without create an instance访问成员、方法,无需创建实例

2.class 2.班级

  • Multiple reference you can create您可以创建多个参考
  • Need to create instance for access members, methods需要为访问成员、方法创建实例

3.companion object 3.伴侣对象

  • A companion object is initialized when the corresponding class is loaded当加载相应的类时初始化一个伴生对象
  • In object MyClass{} by default whole variable have single reference but in companion object you have choice to create static method or to create static variable默认情况下,在object MyClass{} ,整个变量具有单一引用,但在companion object您可以选择创建静态方法或创建静态变量
  • You can create singleton class您可以创建单例类

4.data class 4.数据类

  • Classes that are used to hold data/state用于保存数据/状态的类
  • Kotlin's data classes, you don't need to write/generate all the lengthy boilerplate code yourself Kotlin 的数据类,你不需要自己编写/生成所有冗长的样板代码
  • The compiler automatically generates a default getter and setter for all the mutable properties编译器自动为所有可变属性生成默认的 getter 和 setter
  • The compiler automatically derives the implementation of standard methods like equals() , hashCode() and toString()编译器自动导出标准方法的实现,如equals()hashCode()toString()

Examples例子

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

Also you can define functions without object declaration.您也可以在没有对象声明的情况下定义函数。 Just in .kt file For example:只是在 .kt 文件中例如:

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

And this function was related to package where is .kt file is declared.这个函数与声明 .kt 文件的包有关。 You can read more about it here https://kotlinlang.org/docs/reference/packages.html你可以在这里阅读更多关于它的信息https://kotlinlang.org/docs/reference/packages.html

Building on @speirce7's answer:基于@speirce7 的回答:

The following code shows the basic difference between a Class and an Object when it comes to Kotlin:以下代码显示了 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