Kotlin学习笔记3-6 类和对象-数据类

时间:2021-07-25 20:06:21

数据类

Kotlin官网:Classes and Objects-Data Classes
数据类指专门用来保存数据的类,用data关键字声明。

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

Kotlin针对数据类常用的格式,编译器自动生成一些函数

  • equals()和hashCode()
  • toString()
  • componentN()
  • copy()

为保证生成的函数有效,数据类需要满足以下要求

  • 主构造函数至少有一个参数
  • 所有主构造函数的参数必须声明为成员(var或val修饰)
  • (版本<1.1)数据类只能实现接口

另外,对于继承来的成员,遵循以下规则

  • 自己已显式实现equals,hashCode,toString,或者父类是final的实现,则使用已有函数实现,不会生成
  • 如果父类有componentN()函数,可继承的(open修饰),并且返回类型兼容,数据类会生成并重写父类函数。否则,无法重写(函数签名不符或父类函数为final)则报错。
  • 一个有签名相符的copy函数的类,从这个类派生一个数据类,在1.2中被废弃,在1.3中被禁止。(大意就是父类不能有签名相符的copy函数)
  • 禁止显式实现componentN()和copy()函数

Kotlin1.1后可以继承普通类(见3-7密封类)
在JVM平台,如果是被生成的类,需要无参构造函数,可以通过为每个主构造函数的参数指定默认值实现。(JVM上,主构造函数有参,并且所有参数都有默认值,Kotlin会生成一个默认无参的次构造函数,使用所有的默认值调用主构造函数,见3-1类和接口:构造函数)

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

复制

当需要一个新的对象,大部分属性和原有对象相同,只改动其中几个,这时就用到了复制。
Kotlin自动为数据类生成copy函数,实现如下:

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

使用如下:

val jack = User(name = "Jack", age = 1)
val olderJack = jack.copy(age = 2)

数据类和解构声明

数据类的compentN函数会自动生成,可以直接使用解构声明(见5-1解构声明)

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

标准数据类

标准库中提供了PairTriple类,都在kotlin包中。
Pair:

public data class Pair<out A, out B>(
        public val first: A,
        public val second: B
                                    ) : Serializable {

    /** * Returns string representation of the [Pair] including its [first] and [second] values. */
    public override fun toString(): String = "($first, $second)"
}

Triple:

public data class Triple<out A, out B, out C>(
        public val first: A,
        public val second: B,
        public val third: C
                                             ) : Serializable {

    /** * Returns string representation of the [Triple] including its [first], [second] and [third] values. */
    public override fun toString(): String = "($first, $second, $third)"
}