Kotlin 类和对象的区别

我刚到 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;
}
}

改变信仰的科特林:

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

如能提供任何帮助,我将不胜感激。

47031 次浏览

Kotlin 对象就像一个无法实例化的类,因此必须通过名称来调用它。(静态类本身)

Android 转换器发现您的类只包含一个静态方法,因此它将其转换为 Kotlin 对象。

点击这里阅读更多内容: http://petersommerhoff.com/dev/kotlin/kotlin-for-java-devs/#objects

也可以不用对象声明定义函数 例如:

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

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

一个对象是一个单例对象,你不需要创建一个实例来使用它。

需要实例化类才能使用

就像在 Java 中你可以说 Math.sqrt (2) ,你不需要创建一个数学实例来使用 sqrt 一样,在 Kotlin 你可以创建一个对象来保存这些方法,它们实际上是静态的。

这里有一些信息:

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

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

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

科特林为什么要引入 object

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

与 Java 的互操作性:

因为 Kotlin 与 Java 是100% 可互操作的,所以有时候您会希望以一种更适合 Java 阅读的方式公开某些 API 或字段。为此,可以使用 @JvmStatic注释。通过使用 @JvmStaticobject中的字段或函数进行注释,它可以编译成 Java 可以更容易使用的静态字段。

伴侣物品:

最后一件值得一提的事情是 companion object。在 Java 中,典型的类有一些静态内容,但也有一些非静态/实例内容。Kotlin 允许您对伴随对象进行类似的操作,伴随对象是绑定在 class上的 object,这意味着类可以访问伴随对象的私有函数和属性:

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

基于@speirce7的回答:

下面的代码显示了 Class 和 Object 在 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.
}

区别: 对象 | | 同学们 | | 同伴物体 | | 资料类别

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)