前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >转向Kotlin——数据类和封闭类

转向Kotlin——数据类和封闭类

作者头像
蜻蜓队长
发布2018-08-03 10:55:44
8970
发布2018-08-03 10:55:44
举报
文章被收录于专栏:Android机动车Android机动车
数据类和封闭类是Kotlin中的两种特殊的类,今天一起了解一下。

数据类是Kotlin的一个语法糖。Kotlin编译器会自动为数据类生成一些成员函数,以提高开发效率。

数据类的使用

无论是Java服务器开发还是Android开发,实体类自然是特别熟悉,它就是讲json格式转化为一个只包含数据和基本操作方法的实体类,以方便网络存取和数据库存取。

我们总是需要一个类来表示数据,例如要表示一个用户的数据,我们会创建一个User类,并通过构造器传入两个属性:

代码语言:javascript
复制
class User(name: String, age: Int) {
    var mName = name
    var mAge: Int = age
}

我们定义实体类,除了要保存数据之外,还需要输出对象的值,比较对象等操作,前者会用到toString函数,后者会用到equals函数,如下:

代码语言:javascript
复制
var user1 = User("js", 20)
var user2 = User("lx", 12)
println(user1)
println(user2)
println(user1.equals(user2))

输出结果是:

代码语言:javascript
复制
User@3764951d
User@4b1210ee
false

从结果可以看出,输出User的两个对象时,调用了这两个对象的toString方法,但toString函数默认会调用hashcode函数,输出当前对象的hashcode,并在前面加上 类名@

对象的equals方法默认也是比较了两个对象的hashcode,两个对象hashcode不同,自然返回false。

有时我们的业务需求是这样的:打印对象,即按规则打印对象的所有属性,两个对象的所有属性值相同,则返回两个对象相等,于是乎我们需要重写toString函数和equals函数,相信大家都会写,这里就不再累赘了。

尽管前面写的User类实现了我们的需求,但会不会也太麻烦了,每个类都需要重写toString和equals等方法。为了提高开发效率,Kotlin加入了我们马上要介绍的数据类。

所谓数据类,就是只定义必要的部分,其余部分可以自动生成。

从上面的类可以看出,只有name和age是必须的,其余的都是可以自动推导的。数据类规定:属性要通过主构造器指定,而且还要在class关键字之前加data。我们再写一个数据类,如下:

代码语言:javascript
复制
data class Person(var name: String, val age: Int)

可以看出,原本十几行几十行的代码,现在一行就搞定了,其余的Kotlin编译器会自动生成。

数据类也和普通类一样,也可以继承其他类,有一些其他的成员函数等。

编写一个数据类需要注意:

  • 主构造器至少要有一个参数;
  • 主构造器的参数要用var或val修饰;
  • 数据类不能是抽象类、open类、封闭类或者内部类。

由于主构造器中必须至少要有一个参数,所以在数据类中,不可能存在无参的主构造器,要想让数据类用友一个无参的构造器,有以下两种方法:

  1. 为主构造器的每一个参数都加上默认值;
  2. 添加一个没有参数的次构造器,并调用主构造器同时制定各参数。
代码语言:javascript
复制
data class MPerson(var name: String = "js", var age: Int = 20)
data class NPerson(var name: String, var age: Int) {
    // 次构造器,this调用猪狗早起,并指定参数
    constructor() : this("js", 20)
}

对象的复制

在开发中,我们经常需要复制一个对象,然后修改它的一部分属性,这就需要一个复制机制,Kotlin除了为数据类自动生成toString方法和equals方法,还默认生成了一个copy方法,它的作用就是复制数据类的实例。代码如下:

代码语言:javascript
复制
var person = Person("wj", 20)
var mCopyPerson1 = person.copy()
var mCopyPerson2 = person.copy(name = "js")

数据类成员的解构

所谓解构,就是解除解构,指的是将数据对象中的属性提取出来,分别赋给单个变量。

Kotlin编译器会自动为数据类生成组件函数(以后会说到),隐藏,可以直接将数据类成员解构:

代码语言:javascript
复制
var js = Person("Js", 20)
// 将js.name和js.age分别赋给name和age变量
var (name, age) = js
println("$name, is $age years old")

封闭类

封闭类可以看作是枚举的扩展。一个封闭类,前面用sealed关键字标识。可以有人以多个子类和对象。封闭类的值只能是这些子类和对象。

使用封闭类的好处是when表达式,不需要再使用else形式了。看个例子:

代码语言:javascript
复制
sealed class Expr
data class Const(var count: Int) : Expr()
data class Sun(var e1: Expr, var e2: Expr) : Expr()
fun evel(expr: Expr): Int = when (expr) {
    is Const -> expr.count
    is Sun -> evel(expr.e1) + evel(expr.e2)
}

总结

在Kotlin中提供了一些特殊的类,其中数据类和封闭类就是其中的两个。尽管这些特殊的类并不是必须的,但有些时候使用它们会给我们的开发带来很大的方便,尤其是数据类。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-05-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Android机动车 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 数据类的使用
  • 对象的复制
  • 数据类成员的解构
  • 封闭类
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档