get/set方法

声明一个属性的完整语法是

var <propertyName>[: <PropertyType>] [= <property_initializer>]
[<getter>]
[<setter>]

PropertyType、property_initializer、getter、setter均是可选的元素,这里再强调下,val类型变量为可读变量,所以只拥有get方法,而var类型则有get/set方法。这里直接自定义Student类的birthday的get/set方法

class Student {
...
var age: Int?//自定义get/set方法
get() = field //使用备用字段自定义get/set方法
set(value) {//value是自定义的变量名,名字可以随便起
age = value
}
...
}

接口

Kotlin 的接口与 Java 8 类似,既包含抽象方法的声明,也包含实现。与抽象类不同的是,接口无法保存状态。它可以有属性但必须声明为抽象或提供访问器实现。

public interface SomeInterface{
var value:String //默认abstract fun reading() // 未实现 fun writing(){ //已实现
// do nothing
}
}
class MyImpl:SomeInterface{
override var value: String = "jason" //重载属性
override fun reading() {
// 方法体
}
}

枚举

枚举类的最基本的用法是实现类型安全的枚举

enum class Direction {
NORTH, SOUTH, WEST, EAST
}

每个枚举常量都是一个对象。枚举常量用逗号分隔。

使用:

 var color:Color=Color.BLUE
println(Color.values())
println(Color.valueOf("RED"))
println(color.name)
println(color.ordinal)//返回下标

委托

委托模式是一个很有用的模式,它可以用来从类中抽取出主要负责的部分。委托模式是Kotlin原生支持的,所以它避免了我们需要去调用委托对象。委托者只需要指定实现的接口的实例。

interface Base {
fun print()
} class BaseImpl(val x: Int) : Base {
override fun print() { print(x) }
} class Derived(b: Base) : Base by b fun main(args: Array<String>) {
val b = BaseImpl(10)
Derived(b).print() // 输出 10
}

在 Derived 声明中,by 子句表示,将 b 保存在 Derived 的对象实例内部,而且编译器将会生成继承自 Base 接口的所有方法, 并将调用转发给 b。

委托属性

kotlin通过属性委托的方式,为我们实现了一些常用的功能,包括:

  1. 延迟属性(lazy properties): 其值只在首次访问时计算,
  2. 可观察属性(observable properties): 监听器会收到有关此属性变更的通知,
  3. 把多个属性储存在一个映射(map)中,而不是每个存在单独的字段中。

延迟属性

延迟属性我们应该不陌生,也就是通常说的懒汉。

//标准委托 延迟属性
val lazyValue : String by lazy {
Log.d("m", "只执行1次")
"value"
}
 println(lazyValue)
println(lazyValue) //执行
D/m: 只执行1次
I/System.out: value
I/System.out: value

可观察属性 Observable

Delegates.observable() 接受两个参数:初始值和修改时处理程序(handler)。 每当我们给 属性赋值时会调用该处理程序(在赋值后执行)。它有三个参数:被赋值的属性、旧值和新 值:

class User {
var name: String by Delegates.observable("<no name>") {
prop, old, new ->
println("$old -> $new")
}
}
//可观察属性 Observable
val user = User()
user.name = "first"
user.name = "second"
//执行结果
I/System.out: <no name> -> first
I/System.out: first -> second

把属性储存在映射中

一个常见的用例是在一个映射(map)里存储属性的值。 这经常出现在像解析 JSON 或者做其他“动态”事情的应用中。 在这种情况下,你可以使用映射实例自身作为委托来实现委托属性。

class MapUser(val map: Map<String, Any?>) {

    val name: String by map
val age: Int by map
}
//把属性储存在映射
val userMap = MapUser(mapOf(
"name" to "小七",
"age" to 21
))
println(userMap.name)
println(userMap.age)
//执行结果
I/System.out: 小七
I/System.out: 21

Kotlin------类和对象(二)的更多相关文章

  1. C++中的类和对象(二)

    一,对象的动态建立和释放 1.什么是对象的动态建立和释放 通常我们创建的对象都是由C++编译器为我们在栈内存中创建的,我们无法对其进行生命周期的管理.所以我们需要动态的去建立该对象,因此我们需要在堆内 ...

  2. Kotlin 类和对象

    类定义 Kotlin 类可以包含:构造函数和初始化代码块.函数.属性.内部类.对象声明. Kotlin 中使用关键字 class 声明类,后面紧跟类名: class Runoob { // 类名为 R ...

  3. php类和对象(二)

    面向对象第三大特性:多态 概念: 当父类引用指向子类实例的时候,由于子类对父类函数进行了重写,导致我们在使用该引用取调用相应方法时表现出的不同 条件: 1.必须有继承 2.子类必须对父类的方法进行重写 ...

  4. python cookbook第三版学习笔记十一:类和对象(二)调用父类的方法

    在子类中调用父类的方法,可以下面的A.spam(self)的方法. class A(object):     def spam(self):         print 'A.spam' class ...

  5. c++ 吕凤翥 第六章 类和对象(二)

    c++ 吕凤翥 第六章 类和对象(二) 指针   引用  和数组 一:对象指针和对象引用 1.指向类的成员的指针 分为指向成员变量和指向成员函数两种指针 成员变量的格式:     类型说明符  类名: ...

  6. Kotlin语法(类和对象)

    二.类和对象: 1. 类定义: 类的声明包含类名,类头(指定类型参数,主构造函数等等),以及类主体,用大括号包裹.类头和类体是可选的:如果没有类体可以省略大括号. class Invoice{ } 2 ...

  7. Kotlin基础(三)类、对象和接口

    类.对象和接口 一.定义类的继承结构 一)Kotlin中的接口 Kotlin的接口与Java8中相似,它们可以包含抽象方法的定义以及非抽象方法的实现,但它们不能包含任何状态. interface Cl ...

  8. oc语言学习之基础知识点介绍(二):类和对象的进一步介绍

    一.类.对象在内存中的存储 /* 内存分区: 栈:局部变量 堆:程序员自己写代码申请开辟的 程序员自己维护,编译器现在帮我们自动优化了,它在合适的给我们加上了释放空间的语句,所以我们现在写的对象不会造 ...

  9. day 22 二十二、面向对象导入、名称空间、类与对象

    一.面向对象导入 1.含义: ①面向过程: 重过程:解决问题,考虑的是解决问题的流程 解决问题的思路清晰,但拓展性不强 ②面向对象: 重对象:解决问题,找到解决问题的对象 解决问题的思路可能不止一条( ...

  10. 类与对象 - Java学习(二)

    弄清楚类与对象的本质与基本特征,是进一步学习面向对象编程语言的基本要求.面向对象程序设计与面向过程程序设计在思维上存在着很大差别,改变一种思维方式并不是一件容易的事情. 一.面向对象程序设计 程序由对 ...

随机推荐

  1. linux 目录与文件命令

    目录与文件常用命令 1.cd命令 cd [相对路径或绝对路径或特殊符号] 功用:变换目录 ps: 不加参数时,默认切换到用户主目录,即环境变量HOME指定的目录,如root用户的HOME变量为/roo ...

  2. list_for_each_entry解析

    双向链表及链表头: 建立一个双向链表通常有一个独立的用于管理链表的链表头,链表头一般是不含有实体数据的,必须用INIT_LIST_HEAD()进行初始化,表头建立以后,就可以将带有数据结构的实体链表成 ...

  3. matplotlib中的legend()—显示图例

    源自  matplotlib中的legend()——用于显示图例 -- 博客园 http://www.cnblogs.com/yinheyi/p/6792120.html legend()的一个用法: ...

  4. [golang note] 变量常量

    变量 • 变量声明 √ golang变量声明的关键字为var. √ golang变量声明时类型信息放置在变量名之后. ▶ 单个变量声明 ▪ 语法如下 var name type ▪ 示例如下 var ...

  5. vue 项目中assets文件夹与static文件夹引用的区别

    首先,assets文件夹和static文件夹在vue-cli生成的项目中,都是用来存放静态资源的. 1.assets目录中的文件会被webpack处理解析为模块依赖,只支持相对路径形式.build的时 ...

  6. XDU 1001 又是苹果(状态压缩)

    #include<cstdio> #include<cstring> ; using namespace std; int r[maxn],c[maxn]; char pic[ ...

  7. RabbitMQ 如何实现对同一个应用的多个节点进行广播

    1.背景 了解过RabbitMQ的Fanout模式,应该知道它原本的Fanout模式就是用来做广播的.但是它的广播有一点区别,来回顾下它的含义:Fanout类型没有路由键的概念,只要队列绑定到了改ex ...

  8. Win10应用《纸书科学计算器》更新啦!

    <纸书科学计算器>在2016年8月拿了计算机设计大赛国家一等奖,现在仍记得我在答辩时还给评委们普及了一波UWP平台的知识.受此鼓励,这款应用也不会停下更新的脚步^_^.最近从1.9小幅升级 ...

  9. $一步一步学Matlab(4)——使用Matlab进行初等数学运算

    Matlab可以看成是一个功能强大的计算器,那么既然是计算器,进行基本的数学运算绝对是必不可少的.本文主要讲解如何用Matlab做初等数学运算,所谓"初等数学运算",可以理解成是小 ...

  10. Uninstalling JIRA applications from Linux

     If you wish to re-install JIRA in 'unattended mode', do not uninstall your previous installation of ...