Kotlin系列(十七):面向对象之简洁好用的数据类
目录
- 更多分享:www.catbro.cn
一、前言:
- 数据类其实是Kotlin为了简化我们编程中不必要的一些操作而封装的一个类,如果你要追根究底的话,其原理很简单,就是kotlin在将其编译为class时,自动额外帮我们做了一些约定俗成,我们不想干的事情,释放我们的双手。
- 对于Java程序员来说_JavaBean_这种类一定不陌生,其主要是用来定义数据类型。JavaBean的特点是一般对于每个字段我们都需要生成set和get方法,如果JavaBean中成员少还可以,当JavaBean的成员很多时,往往整个JavaBean类里都是自动生成的set和get方法,虽然是自动生成的,但还是影响了美观度和阅读性。
- 对此,Kotlin为我们创造了数据类这个类型。
- 以下学习参考自官方学习文档。
二、数据类
- 我们经常创建一些只保存数据的类。 在这些类中,一些标准函数往往是从数据机械推导而来的。
- 在 Kotlin 中,这叫做 数据类 并标记为
data
。
数据类的声明语法:
-
声明一个数据类的完整格式:
data class <类名><(主构造函数参数列表)>[: 继承类和实现接口][{/*类体*/}]
-
OK,现在我们可以声明一个简单的数据类:
data class User(val name: String, val age: Int)
-
编译器自动从主构造函数中声明的所有属性导出以下成员:
- 1、
equals()
/hashCode()
对;
- 2、
toString()
格式是"User(name=John, age=42)"
; - 3、
componentN()
函数 按声明顺序对应于所有属性; - 4、
copy()
函数(见下文)。
- 以上便是Kotlin为了释放我们的双手为我们做的。其中componentN()这个函数很有趣,其实现的最终效果有点类似Python,js中用元组来接收数据。
数据类必须满足一定的要求
- OK,为了确保生成的代码的一致性和有意义的行为,数据类必须满足以下要求:
- 1、主构造函数需要至少有一个参数;
- 2、主构造函数的所有参数需要标记为
val
或var
; - 3、数据类不能是抽象、开放、密封或者内部的;
- 4、(在1.1之前)数据类只能实现接口。
成员生成需要遵循的规则
- 成员生成遵循关于成员继承的这些规则:
- 1、如果在数据类体中有显式实现
equals()
、hashCode()
或者toString()
,或者这些函数在父类中有
- 2、final*{: .keyword } 实现,那么不会生成这些函数,而会使用现有函数;
- 3、如果超类型具有 open{: .keyword } 的
componentN()
函数并且返回兼容的类型, 那么会为数据类生成相应的函数,并覆盖超类的实现。如果超类型的这些函数由于签名不兼容或者是 final 而导致无法覆盖,那么会报错; - 4、不允许为
componentN()
以及copy()
函数提供显式实现。
-
自 1.1 起,数据类可以扩展其他类,如密封类,后面我们将会学习。
-
在 JVM 中,如果生成的类需要含有一个无参的构造函数,则所有的属性必须指定默认值。
-
示例代码如下:
data class User(val name: String = "", val age: Int = 0)
三、copy复制
-
前面我们说到,数据类会自动为我们创建copy函数。
-
在很多情况下,我们需要复制一个对象改变它的一些属性,但其余部分保持不变。
copy()
函数就是为此而生成。对于上文的User
类,其实现会类似下面这样:fun copy(name: String = this.name, age: Int = this.age) = User(name, age)
-
下面我们可以通过copy函数来使用原对象的一些属性值,但是修改一些新的值来创建新的对象:
val jack = User(name = "Jack", age = 1) val olderJack = jack.copy(age = 2) println(jack) println(olderJack) println(jack===olderJack)
-
结果输出为:
User(name=Jack, age=1) User(name=Jack, age=2) false
-
可以看到,其值发生了改变,对象也是不同的对象
四、数据类和解构声明
-
为数据类生成的 Component 函数 使它们可在解构声明中使用:
val jane = User("Jane", 35) val (name, age) = jane println("$name, $age years of age") // 输出 "Jane, 35 years of age"
-
是不是感觉其很想python的元组的用法, 后面我们会单独分一章节来学习Component函数
五、总结
- 本章节我们主要学习了Kotlin中的数据类,所以在使用Kotlin时,我们可以用数据类来替换Bean类,减少不必要的操作,提高生产率。