Kotlin类与属性及构造函数的使用详解
作者:niuyongzhi 发布时间:2021-06-04 06:04:20
1.类的属性 filed
1)在kotlin中定义属性,必须赋初始值,要不编译器检查不通过。这个和java不同
2)kotlin会针对于定义的每个属性都封装了一个field,用于存储数据。
3)针对于非private的var(可变)属性,kotlin默认会生成一组getter和setter方法,通过反编生成的byteCode代码可以看到定义的setter和getter方法。
4 )针对于非private的val(不可变)属性,kotlin只生成了getter方法,没有setter方法,因为定义为val的属性,是不允许修改的。
5)我们也可以在属性后面,复写getter和setter方法,自己定义要实现的内容。
6)针对于private关键字修饰的属性,kotlin不对外提供setter和getter方法。尽管我们能够复写这两个方法。外界还是不能够访问。这点和Java有很大的不同。
class Person {
//针对于定义的每个属性,都有一个filed进行封装。
//对于非private的属性,都会生成一对getter和setter方法
//我们也可以自己定义这俩方法
var name = ""
get() = field.plus("_01")
set(value) {
field = value.uppercase()
}
//对于val的属性,kotlin不听过setter方法
val age = 0
get() = field + 1
//对于private属性,kotlin不提供getter和setter方法。
//虽然我们已经复写了,但是外界还是不够能访问,这个和java的区别很大。
private var subject = ""
get() = "Kotlin"
set(value) {
field = value
}
}
fun main() {
val person = Person()
person.name = "LiLei"
println(person.name)
println(person.age)
}
2.构造函数
1)定义在class 类名 后面的构造函数,是类的主构造函数。这个和java不一样,可以直接定义在类上
2)在主构造函数中,可以使用临时变量给类属性赋值,为了方便识别,在kotlin中,临时变量通常会以下划线开头_属性名。如_name:String
3)在主构造函数中,可以同时定义临时变量和类属性,要加上var或val修饰符。如var age:Int
4)在属性参数后直接设置默认值。创建对象时,默认参数可以不传。如var subject:String="Kotlin"
5通过constructor() : this可以定义次构造函数
6)通过init{}定义初始化块,对所传参数进行有效性检查。初始化块会在构造类实例时执行。
//定义在class 类名 后面的构造函数,是类的主构造函数。
//在主构造函数中,可以使用临时变量给类属性赋值,为了方便识别,在kotlin中,临时变量通常会以下划线开头_属性名。
//也可以在主构造函数中,可以同时定义临时变量和类属性,要加上var或val修饰符。
//还可以在属性后直接设置默认值。创建对象时,默认参数可以不传。
class Person(_name: String, var age: Int, var subject: String = "Kotlin") {
var name = _name
get() = field.plus("_01")
set(value) {
field = value.lowercase()
}
//次构造函数
constructor(_name: String, _age: Int) : this(_name, _age, "Java"){
this.name = _name.trim()
}
//无参是次构造函数
constructor() : this("", 1, "")
//初始化代码块
init {
//通过require函数,对属性值做合规判断。如果
require(age > 0) { "age must be >0" }
require(name.isNotEmpty()){"name can not be empty"}
}
}
fun main() {
val person = Person("LiLei ", 18)
println(person.name)
println(person.age)
println(person.subject)
}
3.执行顺序
对应属性,可以通过主构造函数、类属性、初始化代码块、和次级构造函数,来进行初始化。
那么他们的执行顺序就是上面这个顺序。这个执行顺序要牢记,很关键,有可能会踩到坑。
4.延迟初始化
通过 lateinit这个关键字,实现延迟初始化。属性可以在声明时,不必赋初始值。但是在使用前必须赋值。可以通过::hobby.isInitialized 这个来判断是否初始化完成。
lateinit var hobby:String
fun initHobby(){
hobby="game"
}
fun isInit():Boolean{
//判断属性是否初始化
return ::hobby.isInitialized
}
5.惰性初始化
通过by lazy可以实现惰性初始化。属性声明时不必赋值,使用这个属性时,会自动初始化。
val lazy by lazy { lazyinit() }
private fun lazyinit() :Boolean{
println("lazy init")
return true
}
来源:https://blog.csdn.net/niuyongzhi/article/details/126575708


猜你喜欢
- 1. 添加maven依赖包<dependency> <groupId>org.apache.calcit
- 在熟悉hutool工具包时出现的关于Assert.assertEquals()的报错及其解决方法前提(也是主要问题)用testCompile
- SpringMVC获取表单数据1、实体类package cn.hadron.bean;import java.io.Serializable
- 这里我先简单描述一下需求:服务器返回的是html页面的一部分带有标签的内容。解决的思路是:将服务器返回的内容片段拼凑成一个完整的页面。下面直
- 一、Android Studio 主题的设置1.1 设置Android Studio 自带的主题及包名字体大小1.2 导入第三方主题:下载了
- Chart折线图使用鼠标滚轮放大、缩小和平移曲线使用鼠标滚轮滚动放大和缩小X轴的宽度,鼠标左键按住拖动实现曲线的左右平移,不再使用滚动条。添
- 目录类划分时关于内聚性的问题静态类的设计高内聚类的设计附:面向过程编程中模块的内聚性偶然内聚或巧合内聚(Coincidental)逻辑内聚(
- 从何说起前些天和朋友讨论一个问题,他们的应用有几十万会员然后对应有积分,现在想做积分排名的需求,问有没有什么好方案。这个问题也算常见,很多地
- Java BufferWriter写文件之后文件是空的或者数据不全在编程的过程中,读写文件是非常常见的操作,在这里我问介绍一下最近我遇到的集
- redissonredisson 实现分布式锁的机制如下:依赖版本implementation 'org.redisson:redi
- 服务端package lesson02;import java.io.*;import java.net.ServerSocket;impo
- 写在前面jenkins作为java的好 * ,经历过单体项目时代->集群项目时代->容器集群分布式时代,使用稳定可靠,cpu友好(
- 一、@Configuration1.1 未加@Configuration<!--logback-test.xml,配置不打印日志--&
- 目录引入依赖Java中使用GraphQL的API无参数简单查询带参数简单查询GraphQL可以通过Java的API来实现数据的查询,通过特定
- c#判断代码是否执行超时一、使用委托delegate void dg();dg dgCase;void method(){ &n
- Android 破解视频App去除广告功能作为一个 * 丝程序猿也有追剧的时候,但是当打开视频app的时候,那些超长的广告已经让我这个 * 丝无法忍
- Java 里的 * 是动态拦截 action 调用的对象,它提供了一种机制可以使开发者可以定义在一个 action 执行的前后执行的代码,也
- 关于 LoadLibrary 的疑问Win32 API 中 LoadLibrary 函数的功能是加载某个库文件(通常是 dll 文件),然后
- 我们开发一个Spring Boot项目,肯定要导入许多的静态资源,比如css,js等文件如果我们是一个web应用,我们的main下会有一个w
- 本文实例讲述了Android中SeekBar和RatingBar用法。分享给大家供大家参考,具体如下:什么是SeekBar?可以拖动的进度条