欢迎关注 二师兄Kotlin
转载请注明出处 二师兄kotlin
数据类
我们经常创建一个只保存数据的类。在这样的类中一些函数只是机械的对它们持有的数据进行一些推导。在 kotlin 中这样的类称之为 data 类,用 data 标注:
data class User(val name: String, val age: Int)
编译器会自动根据主构造函数中声明的所有属性添加如下方法:
-- equals()/hashCode 函数
-- toString 格式是 "User(name=john, age=42)"
--componentN()
functions对应按声明顺序出现的所有属性
-- copy() 函数
为确保这些生成代码的一致性,并实现有意义的行为,数据类要满足下面的要求:
-- 主构造函数应该至少有一个参数;
-- 主构造函数的所有参数必须标注为 val 或者 var ;
-- 数据类不能是 abstract,open,sealed,或者 inner ;
-- (在1.1之前)数据类只能实现接口。
另外,members generation 遵循关于成员继承(members inheritance)的一些规则:
如果在数据类中明确实现了
equals()
,hashCode()
或者toString()
,或者 在超类中的final 实现(final implementations in a superclass),那么这些函数将不会再被自动生成,会使用已存在的实现。
如果超类中存在componentN()
函数,且是open
修饰的且返回通用类型(compatible types),数据类相对应的函数就会被生成并且覆盖超类。如果超类的函数不能被复写的原因归结于不兼容的方法签名或者是final修饰的,将会上报一个error。
从拥有函数copy(...)
的类去派生一个数据类在Kotlin1.2中已经过期了,而且将会被在Kotlin1.3中禁止掉。
为componentN()
和copy()
函数提供明确的实现是不被允许的。
从1.1开始数据类可以继承其它类(参考Sealed classes )
在JVM中,如果生成类必须有一个有参构造函数,所有属性的默认值都需要被指定
data class User(val name: String = "", val age: Int = 0)
复制(Copying)
常常会有这样的场景,我们需要复制一个对象,修改部分属性,其他属性保持不变。此时就需要copy()
函数。 比如上面的User
类, 它的实现可能如下:
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)
数据类以及解构声明
组件函数允许数据类在多重声明中使用:
val jane = User("Jane", 35)
val (name, age) = jane
println("$name, $age years of age") // prints "Jane, 35 years of age"
标准的数据类
标准库提供了两个功能类 Pair
和 Triple
,大多数情况下,指定的数据类将会是一个不错的选择,因为它们提供有意义的属性名称,代码可能性很不错。
下一节将会涉及泛型。