类
类与 field
- 自动生成 get() = field 和 set(vale) field = value field = 属性的值
- 计算属性 编译成 java 字节代码的时候代码会省略属性成员; 只留下一个 getVersionCode(){ return 88 } 的方法
- 只读只生成 get 方法
如果定义 set 和 get 方法编译报错, 所以需要修改已定义的 set 或 get 方法
fun main() {
val appInfo = AppInfo()
println(appInfo.getInto())
//自动生成
appInfo.versionName = "?"
println(appInfo.versionName)
println(appInfo.versionCode)
}
class AppInfo() {
//自动生成 get() = field 和 set(vale) field = value field = 属性的值
var versionName: String = "1.6.90"
get() = field.plus("1")
set(value) {field = value}
// 计算属性 编译成 java 字节代码的时候一下代码会省略 属性
// 只留下一个 getVersionCode(){ return 88 } 的方法
val versionCode:Int
get() = 88
//只读只生成 get 方法
val v1 :String ="123"
private var info: String? = null
// this?.内置函数 + 空合并操作符号 = 防竞态条件
fun getInto(): String {
return info?.let {
if (it.isBlank()) {
"空字符"
} else {
"非空"
}
} ?: " null "
}
}
防范竞争条件
- this?.内置函数 + 空合并操作符号 = 防竞态条件
fun main() {
println(AppInfo().getInto())
}
class AppInfo() {
private var info: String? = null
// this?.内置函数 + 空合并操作符号 = 防竞态条件
fun getInto(): String {
return info?.let {
if (it.isBlank()) {
"空字符"
} else {
"非空"
}
} ?: " null "
}
}
主构造函数 和 init 代码块
- 这里的主构造函数参数是没有 var val 声明,所以是临时的
- 主构造函数会调用 init 代码块、和成员变量声明
fun main() {
val student = Student("zhangsan", '男', 25, "?")
println(student.sex)
}
class Student(_name: String, _sex: Char, _age: Int, _info: String) {
val name = _name
val sex = _sex
val age = _age
val info = _info
init {
println("主构造")
}
}
次构造函数
- 次构造函数先调用主构造,再调用自身,
- 次构造参数是临时参数
fun main() {
val student1 = Student1( 25, "zhangsan")
println(student1.name)
}
class Student1(val name: String) {
init {
println("主构造")
}
constructor(age: Int, name: String) : this(name) {
println("次构造函数${age}")
}
}
构造函数执行顺序
- 1-4 都是主构造的内容部分
- 2、3、4 是同时生成,看代码顺序
- 次构造函数先调用主构造,再调用自身,
- 主构造函数会调用 init 代码块、成员变量声明看代码顺序
fun main() {
val student1 = Student1( 25, "zhangsan")
println(student1.name)
}
//第一步 生成val name
class Student1(val name: String,_info:String) {
//第二步 生成 info 主构造中的
val info = _info
//第三步 成员变量
val sex:Char ='女'
//第四步 init代码快
init {
println("主构造")
}
//第五步 次构造函数
constructor(age: Int, name: String) : this(name,"") {
println("次构造函数${age}")
}
}
lateinit 延迟初始化
- 尽量不使用
fun main() {
Net().getResult()
}
class Net() {
lateinit var responseResult: String
fun request() {
responseResult = "result"
}
fun getResult(): String {
return if (::responseResult.isInitialized) {
"没有返回值"
} else {
responseResult
}
}
}
lazy 懒加载(调用时才加载)
suspend fun main() {
val n = Net2()
delay(5000)
println(n.responseResult)
}
class Net2() {
val responseResult: String by lazy { getResult() }
private fun getResult(): String {
println("....")
return "没有返回值"
}
}
Any 超类 Any? == Java的 Object
各个平台去实现超类 Any 的方法
对象声明 object Student3 = 单例模式
fun main() {
//Student3.INSTANCE.show()
Student3.show()
}
object Student3{
init {
println("student3 init")
}
fun show() = println("student3 show")
/**
public final static Student3 INSTANCE
privae Student3(){}
static{
Student3 stu3 = new Student3()
INSTANCE = stu3
System.out.println("student3 init")
}
*/
}
对象表达式 object :
- 对象表达式 = Java的匿名内部类
- 对 open、 抽象、接口实现类
fun main() {
//对象表达式 = Java的匿名内部类
val stu4 = object : Stu4() {
override fun add(a: String) {
super.add(a)
println("匿名对象 $a")
}
}
stu4.add("aa")
}
open class Stu4(){
open fun add(a:String){
println("stu4 ${a}")
}
}
伴生对象
- 伴生对象是静态内部类实现
- 伴生对象是单例的
fun main() {
//Stu5.Companion.getName Companion是静态内部类
Stu5.name
}
class Stu5() {
companion object {
val name = "伴生"
}
}
嵌套类 和 内部类
class K20 {
//内部类
inner class K201 {
inner class K2011 {
fun getK2011() {
println("k2011")
}
}
}
//嵌套类
class K202 {
fun getK202(){
println("k202")
}
}
}
fun main() {
K20().K201().K2011().getK2011()
K20.K202().getK202()
}
数据类
- 必须有主构造参数
- 构造参数不能是临时参数
- 不能 abstract open inner sealed 等修饰
- 使用 解构component copy toString equals hashCode 内部函数就使用数据类
fun main() {
// == 是Any超类的 equals 引用比较
println(Stu7("7") == Stu7("7"))
// == 数据类重写equals 对属性值进行比较
println(Stu6("6") == Stu6("6"))
}
//普通类
//set get 构造函数
class Stu7(var name: String) {
}
//数据类
// set get 构造函数 解构component copy toString equals hashCode
data class Stu6(var name: String) {
}
数据类 copy 只执行主构造 不执行次构造
数据类 解构
fun main() {
// == 是Any超类的equals引用比较
println(Stu7("7") == Stu7("7"))
// == 数据类重写equals 对属性值进行比较
println(Stu6("6") == Stu6("6"))
// 默认解构
val name = Stu6("jiegou")
println(name)
}
//普通类
//set get 构造函数
class Stu7(var name: String) {
}
//数据类
// set get 构造函数 解构component copy toString equals hashCode
data class Stu6(var name: String) {
}
运算符重载
class K22(val number: Int) {
operator fun plus(k22: K22): Int {
return number + k22.number
}
}
fun main() {
println(K22(1) + K22(2))
K22(3)
}
枚举类 主要用户:状态的控制
枚举类解决不了的使用密封类
密封类
fun main() {
val k24State = K24State.Idle
checkState(k24State)
}
fun checkState(k24State: K24State) {
when (k24State) {
is K24State.Idle -> {
println("idle")
}
is K24State.End -> {
println("End")
}
K24State.Loading -> {
println("Loading")
}
}
}
sealed class K24State {
data object Idle : K24State()
data object Loading : K24State()
class End(val name: String) : K24State()
}
sealed class K24Intent {
data object Idle : K24Intent()
data object Loading : K24Intent()
class End(val name: String) : K24Intent()
}
接口
接口定义
- 接口默认是 public open 开放
- 接口没有构造方法
- 接口的成员和方法都需要重写实现,
- 实现方法都需要加 override 关键字
fun main() {
println(KK25().getVersion())
}
interface K25 {
val name: String
fun getVersion(): String
}
class KK25 : K25 {
override val name: String
get() = "niming impl"
override fun getVersion(): String {
return "niming version"
}
}