kotlin中普通类和数据类之间有什么区别

Trầ*_*Tâm 24 kotlin

我试图在Kotlin Koans解决任务#6(DataClass).当我在代码中使用普通类时,测试用例失败了.

这是我的数据类代码:

data class Person(val name: String, val age: Int)

fun task6(): List<Person> {
    return listOf(Person("Alice", 29), Person("Bob", 31))
}
Run Code Online (Sandbox Code Playgroud)

这是数据类的结果:

[Person(name=Alice, age=29), Person(name=Bob, age=31)]
Run Code Online (Sandbox Code Playgroud)

这是我正常类的代码:

class Person(val name: String, val age: Int)

fun task6(): List<Person> {
    return listOf(Person("Alice", 29), Person("Bob", 31))
}
Run Code Online (Sandbox Code Playgroud)

这是正常类的结果:

[i_introduction._6_Data_Classes.Person@4f47d241, i_introduction._6_Data_Classes.Person@4c3e4790]
Run Code Online (Sandbox Code Playgroud)

这是否意味着Kotlin中的普通类和数据类之间存在差异.如果是,那是什么?

更新:

谢谢@Mallow,你是对的.这样可行:

class Person(val name: String, val age: Int) {
    override fun toString(): String {
        return "Person(name=$name, age=$age)"
    }
}

fun task6(): List<Person> {
    return listOf(Person("Alice", 29), Person("Bob", 31))
}
Run Code Online (Sandbox Code Playgroud)

cha*_*l03 16

大多数情况下,我们开发人员使用类只保留类中的数据,而其他东西(如几个默认方法和一些其他实现)也占用内存空间,这只是浪费资源.

从官方文档:

我们经常创建一个类,除了保存数据之外什么都不做.在这样的类中,一些标准功能通常可以从数据中机械地导出.在Kotlin中,这称为数据类,并标记为data.

编译器自动从主构造函数中声明的所有属性派生以下成员:

  • equals()/ hashCode()对,
  • toString()形式为"User(name = John,age = 42)",
  • componentN()函数对应于声明顺序中的属性,
  • copy()函数(见下文).如果这些函数中的任何一个在类体中显式定义或从基类型继承,则不会生成它们.

要了解更多信息,请检查数据类

关于结果,从技术上讲,由于toString()方法的实现,你得到的是不同的.data class' toString()方法使用数据类属性和值来形成返回字符串.通用类' toString()方法使用哈希码来形成返回字符串.


Sol*_*olo 13

对于数据类.

编译器自动从主构造函数中声明的所有属性派生以下成员:

equals()/ hashCode()对,

toString()形式为"User(name = John,age = 42)",

componentN()函数对应于声明顺序中的属性,

copy()函数(见下文).

请参阅https://kotlinlang.org/docs/reference/data-classes.html

  • @TrầnĐứcTâm确切地说,它没有"带有可读格式的tostring方法",默认的tostring只是打印类名和地址,如"i_introduction._6_Data_Classes.Person@4f47d241" (3认同)

lmi*_*asf 7

创建主要目标是保存数据的类是很常见的。如果您希望您的类成为您数据的方便持有者,您需要覆盖通用对象方法:

注意:equals()用于结构相等,通常在 with 中实现hashCode()

通常,这些方法的实现很简单,您的 IDE 可以帮助您自动生成它们。但是,在 Kotlin 中,您不必通用所有这些样板代码。如果您将修饰符添加data到您的类中,则会自动为您添加必要的方法。

的返回值toString()的格式为ClassName(parm1=value1, param2=value2, ...)equals()hashCode()方法考虑了主构造函数中声明的所有属性。

copy()方法

当您将一个类标记为数据类时,该方法copy()也会自动生成,它允许您制作现有实例的副本。当您将实例用作 a 的键HashMap或处理多线程代码时,此功能非常方便。

即使数据类的属性不需要为val,即您可以使用var,但强烈建议您使用只读属性,以便使实例不可变。

最后,componentN()当您将类标记为数据类时,编译器也会生成与声明顺序中的属性相对应的函数。

示例代码

class PersonClass(val name: String, val age: Int)
data class PersonDataClass(val name: String, val age: Int)

>>> val ron = PersonClass("Ron", 18)
>>> val harry = PersonDataClass("Harry", 17)
>>> println(ron) // notice the string representation of a regular class
PersonClass@3b6eb2ec
>>> println(harry) // notice the string representation of a data class
PersonDataClass(name=Harry, age=17)
>>> val harryClone = harry.copy() // this creates a copy of the object referenced by harry
>>> val hermione = PersonDataClass("Hermine", 16)
>>> harry == harryClone
true
>>> harry == hermione
false
Run Code Online (Sandbox Code Playgroud)

总之,如果您需要一个数据持有者,您应该使用数据类,这意味着将修饰符添加data到您的类中。这将为您生成以下方法:toString(), equals(), hashCode(), componentN(), and copy(),因此您可以避免编写样板代码。如果您使用常规课程,您将不会拥有所有这些“包括电池”


fay*_*ayz 7

Aclass代表某些数据“类型”及其行为,因此从这个角度来看,data class它与 a 没有任何不同class。但是有一些关于 a 的行为和规则data class使它有点不同:

  1. 调用toString()数据类会转储一个字符串及其所有成员属性。
  2. 它具有按顺序成员属性的componentN方法。getn
  3. 它有一个copy方法,它将成员属性作为参数来制作对象的差异副本。
  4. Adata class打不开。不能继承。
  5. 不可能abstract
  6. 它不能nestedinner或者sealed
  7. 虽然它可以继承、定义抽象方法和实现接口。
  8. data class 属性可以被破坏成单独的变量,例如 val (name, address) = Person("name", "address")
  9. Pair(a, b)内部使用data class.


jit*_*555 6

Data Class包含我们必须在类似 Java 中重写的内部代码 Kotlin 生成equals(), hashCode(), and toString()

科特林:

data class User(val name: String, val age: String)
Run Code Online (Sandbox Code Playgroud)

爪哇:

class Student {
    public final String name;
    public final String age;

    public User(String name, String age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object other) {
        
    }

    @Override
    public long hashCode() {
      
    }

    @Override 
    public String toString() {
        return "User(name=" + name + ",age=" + age + ")";
    }
}
Run Code Online (Sandbox Code Playgroud)

普通班:

  1. 可以是abstract, open, sealed, 或inner但不适合Data Class
  2. 构造函数参数可以不使用 var 和 val 来声明