Kotlin for android学习四:数据类与封闭类

前言

kotlin官网 (中文版)和kotlin教程学习教程的笔记。

一、数据类

  1. 数据类是仅仅包含状态而没有任何可执行的操作,通过data关键字标记:
data class User(val name:String,val age:Int)

然后,编译器会根据主构造器中声明的全部属性,自动推断产生以下成员函数:

  • equals()/hashCode()函数对
  • toString()函数,输出格式为 User(name=**,age=**)
  • componentN()函数群,这些函数与类的属性对应, 函数名中的数字 1 到 N, 与属性的声明顺序一致(详细见下文)
  • copy()函数(详细见下文)

如果上述任意一个成员函数在类定义体中有明确的定义, 或者从基类继承得到, 那么这个成员函数不会自动生成.

  1. 为了保证自动生成的代码的行为一致, 并且有意义, 数据类必须满足以下所有要求:
  • 主构造器至少要有一个参数
  • 主构造器的所有参数必须标记为val或var
  • 数据类不能是抽象类、open类、封闭类、内部类
  • 数据类不能继承自任何其他类(但可以实现接口)

在 JVM 上, 如果自动生成的类需要拥有一个无参数的构造器, 那么需要为所有的属性指定默认值
data class User(val name: String = "", val age: Int = 0)

二、对象复制

我们经常会需要复制一个对象,然后修改它的一部分属性,但保持其他属性不变,这就是自动生成的copy()函数所需要实现的功能。
对于前面示例中的 User 类, 自动生成的 copy() 函数的实现将会是下面这
样:

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

copy()函数的使用方式

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

var jack = User(age = 18)
var oldJack = jack.copy(age = 81)

三、数据类中成员数据的解构

编译器会为数据类生成组件函数(Component function),有了这些函数,就可以在解构声明中使用数据类

var jack = User(age = 18)
val(name,age)=jack
println("$name,$age")//输出jack,18

四、标准库中的数据类

Kotlin 的标准库提供了 Pair 和 Triple 类可供使用.

 val (rank, money)  = Pair(1, "10000")
 println(" $rank -> $money")//输出 1 -> 10000

但是, 大多数情况下, 使用有具体名称的数据了是一种更好的设计方式, 因为, 数据类可以为属性指定有含义的名称, 因此可以增加代码的可读性.

小知识补充

解构声明(Destructuring Declaration)
  1. 将一个对象解构为多个变量,例如val(name,age)=user 这种语法成为解构声明。
  2. 我们已知一个解构声明回一次性创建多个变量,我们声明了两个变量name和age,并可以单独使用这两个变量println(age)println(name)
  3. 解构声明在编译时被分解为以下代码
val name=user.component1()
val age=user.component2()

当然, 还可以存在component3() 和 component4() 等等.

  1. 任何东西都可以作为解构声明右侧的被解构值, 只要可以对它调用足够数量的组件函数(component function).
  2. componentN() 函数需要标记为 operator , 才可以在解构声明中使用.
    举个例子,从一个函数返回两个值:
fun c(age: Int): User {
   return User(age = age)
}
// 由于数据类会自动声明 componentN() 函数, 因此可以在这里使用解构声明.
val (name, age) = c(18)
println(name)
println(age)

但是有时候,我只想要解构部分属性怎么办?

 class User(val name: String, val age: Int) {
    operator fun component1(): Any {
        return age
    }
}
var user = User("name", 10)
val (comp1) = user
println(comp1)//输出10

解构声明与Map

operator fun <K, V> Map<K, V>.iterator(): Iterator<Map.Entry<K, V>> = entrySet().iterator() 
operator fun <K, V> Map.Entry<K, V>.component1() = getKey()
operator fun <K, V> Map.Entry<K, V>.component2() = getValue()
for ((key, value) in map) {
// 使用 key 和 value 执行某种操作
}

五、封闭类(Sealed class)

  1. 封闭类可以限制一个值只允许是某些指定的类型之一,而不允许是其他的类型。
  2. 要声明一个封闭类,需要将 sealed 修饰符放在类名之前.封闭类可以有子类,但所有的子类声明都必须嵌套在封闭类的声明部分之内.但是,从封闭类的子类再继承的子类(间接继承者)可以放在任何地方, 不必在封闭类的声明部分之内.
sealed class Expr {
class Const(val number: Double) : Expr() 
class Sum(val e1: Expr, val e2: Expr) : Expr()
 object NotANumber : Expr()
}

fun eval(expr: Expr): Double = when(expr) {
is Expr.Const -> expr.number
is Expr.Sum -> eval(expr.e1) + eval(expr.e2)
Expr.NotANumber -> Double.NaN
// 不需要 `else` 分支, 因为我们已经覆盖了所有的可能情况
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容