Kotlin中的普通类和数据类之间有什么区别?

Kotlin中的普通类和数据类之间有什么区别?,kotlin,Kotlin,我试图在上解决任务6(数据类)。当我在代码中使用普通类时,测试用例失败了 以下是我的数据类代码: data class Person(val name: String, val age: Int) fun task6(): List<Person> { return listOf(Person("Alice", 29), Person("Bob", 31)) } [Person(name=Alice, age=29), Person

我试图在上解决任务6(数据类)。当我在代码中使用普通类时,测试用例失败了

以下是我的数据类代码:

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

fun task6(): List<Person> {
    return listOf(Person("Alice", 29), Person("Bob", 31))
}
[Person(name=Alice, age=29), Person(name=Bob, age=31)]
以下是我的普通类代码:

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

fun task6(): List<Person> {
    return listOf(Person("Alice", 29), Person("Bob", 31))
}
[i_introduction._6_Data_Classes.Person@4f47d241, i_introduction._6_Data_Classes.Person@4c3e4790]
这是否意味着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))
}
class-Person(val-name:String,val-age:Int){
重写funtostring():String{
return“Person(name=$name,age=$age)”
}
}
乐趣任务6():列表{
返回列表(人物(“爱丽丝”,29岁),人物(“鲍勃”,31岁))
}
用于数据类

编译器自动从所有 在主构造函数中声明的属性:

等于()/hashCode()对

toString()的形式为“User(name=John,age=42)”

按顺序对应于属性的componentN()函数 声明的内容

copy()函数(见下文)


请参见

大多数时候,我们开发人员使用类来仅在类中保留数据。类有一些方法,这些方法需要在保存数据时被覆盖。例如:
hashCode()
equals()

数据类自动处理这些实用程序

从官方文件:

我们经常创建一个只保存数据的类。在这样的类中,一些标准功能通常可以从数据中机械地派生出来。在Kotlin中,这称为数据类,并标记为
data

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

  • 等于()/hashCode()对
  • toString()的形式为“User(name=John,age=42)”
  • 按声明顺序与属性对应的componentN()函数
  • copy()函数(见下文)。 如果这些函数中的任何一个是在类主体中显式定义的,或者是从基类型继承的,则不会生成它
要阅读更多内容,请检查


关于结果,在技术上,由于实现了
toString()
方法,您得到的结果是不同的。数据类“
toString()
方法使用数据类属性和值来形成返回字符串。通用类“
toString()
方法使用哈希代码形成返回字符串。

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

  • -字符串表示法
  • -对象相等
  • -散列容器
注意:
equals()
用于,它通常在与
hashCode()
一起实现

通常,这些方法的实现非常简单,IDE可以帮助您自动生成它们。然而,在Kotlin中,您不必对所有这些样板代码进行通用化。如果将修饰符
数据
添加到类中,则会自动为您添加必要的方法

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

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

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

最后,当您将一个类标记为数据类时,编译器也会按照声明顺序生成与属性对应的函数

示例代码
class PersonClass(val name:String,val age:Int)
数据类PersonDataClass(val名称:String,val年龄:Int)
>>>val ron=个人类(“ron”,18)
>>>val harry=个人数据类(“harry”,17岁)
>>>println(ron)//注意正则类的字符串表示
PersonClass@3b6eb2ec
>>>println(harry)//注意数据类的字符串表示
PersonDataClass(姓名=哈里,年龄=17岁)
>>>val harryClone=harry.copy()//这将创建harry引用的对象的副本
>>>瓦尔·赫敏=PersonDataClass(“赫敏”,16岁)
>>>哈利=哈利克龙
真的
>>>哈利==赫敏
假的

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

a
表示一些数据“类型”及其行为,因此从这个角度来看,
数据类
没有任何区别。但是关于
数据类
有一些特定的行为和规则使得它有点不同:

  • 对数据类调用
    toString()
    ,将转储包含其所有成员属性的字符串
  • 它有
    componentN
    方法,可以
    按成员属性的顺序
    n
    获取成员属性
  • 它有一个
    copy
    方法,该方法将成员属性作为制作对象的差异复制的参数
  • 无法打开
    数据类
    。不能继承
  • 不可能