Kotlin类和对象 (六)--- 数据类 (data class)

1、数据类的定义

我们常常创建一些类,其主要目的是保存数据。在这样的类中,一些标准的功能性和实用性函数自动从数据中生成。在Kotlin中,这样的类被称为数据类,并被标记为数据。例如

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

编译器会从主构造函数中的所有参数自动生成以下成员:

equals()/hashCode()toString()  "User(name=John, age=42)"的形式
componentN() 函数 对应于所有属性的声明顺序
copy() 函数

为确保生成代码的一致性和意义性,数据类必须满足以下要求:

  • 主构造函数至少有一个参数
  • 主构造函数的所有参数 必须 标记为 val 或者 var
  • 数据类不能用 abstract、open、sealed 或者 inner修饰
  • 在1.1 前,数据类只能实现接口;1.1后,可以继承其它类

另外,关于成员继承,成员的生成需要遵循这些规则:

  • 如果数据类的类体中 equals(), hashCode() or toString() 已明确实现或者在父类中 有 final 实现。那么这些函数不会被生成,并且使用现有的实现;
  • 如果超类型中有 open 和返回兼容类型的 componentN() 函数,则为数据类生成相应的函数并覆盖超类型的函数。如果因为 不兼容的签名 或者 变成 final,超类型中的这些函数不能被覆盖,则会报错。
  • 不允许为 componentN()copy() 提供显示的实现

在 JVM 中,如果生成的类需要含有一个无参的构造函数,则所有的属性必须指定默认值。

data class User(val name: String = "", val age: Int = 0)

2、Copying

很多情况下,我们需要复制一个对象来改变它的一些属性,担保持其它部分不变。copy() 函数就是为此而生成。对于上文的 User 类,其实现会类似下面这样:

fun copy(name: String = this.name, val age: this.age) = User(name,age)

我们可以这样用:

val jack = User(name = "Jack", age = 1) or val jack = User("Jack", 1)
val olderJack = jack.copy(age = 2)
 println(olderjack.toString()) // User(name=Jack, age=2)

3、数据类和解构声明

为数据类生成的组件函数 可用于解构声明中:

val jane = User("Jane", 35) 
val (name, age) = jane
println("$name, $age years of age") // prints "Jane, 35 years of age"

4、标准的数据类

标准库提供了 PairTriple。尽管如此,大多数情况下,命名数据类是个更好的选择,因为他们通过为属性提供有意义的名称使得代码更易读。

你可能感兴趣的:(Android)