温馨提示
写博客是为了记录在开发过程中所涉及到的技术以及遇到的问题的解决,如果该博客对您有所帮助,希望可以点个关注/喜欢;如果您对文章中的内容有什么不同的见解,欢迎留言进行讨论。谢谢!
一、面向对象的概念
- 本质上就是解决如何用程序描述世界的问题
- 讨论如何把实际存在的东西映射成程序的类和对象
- 一种程序设计的思路、思想、方法
- 程序设计层面的概念
- 设计模式:前人的程序设计经验
二、抽象类与接口
相当于半成品与协议
1、接口
- 接口,直观理解就是一种约定
interface InputDevice{
fun input(event: Any)
}
- 接口不能有状态
- 必须由类对其进行实现后使用
2、抽象类
- 实现了一部分协议的半成品
- 可以有状态,可以有方法实现
- 必须由子类继承后使用
3、抽象类和接口的共性
- 比较抽象,不能直接实例化
- 需要有子类(实现类)实现的方法
- 父类(接口)变量可以接受子类(实现类)的赋值
3、抽象类和接口的区别
- 抽象类有状态,接口没有状态
- 抽象类有方法实现,接口只能有无状态的默认实现
- 抽象类只能单继承,接口可以多实现
- 抽象类反应本质,接口体现能力
三、类的继承与接口的实现
- 父类需要 open 才可以被继承
- 父类方法、属性需要 open 才可以倍复写
- 接口、接口方法、抽象类默认为 open
- 复写父类(接口)成员需要 override 关键字
- class D:A(),B,C
- 注意继承类时实际上调用了父类构造方法
- 类只能单继承,接口可以多实现
接口代理
- class Manager(driver: Driver):Driver by driver
- 接口方法实现交给代理类实现
接口方法冲突
- 接口方法可以有默认实现
- 签名一致且返回值相同的冲突
- 子类(实现类)必须复写冲突方法
- super<[父类(接口)名]>.[方法名]([参数列表])
四、类及其成员的可见性
Kotlin | Java |
---|---|
private | private |
protected | protected |
-- | default(包内可见) |
internal(模块内可见) | -- |
public | public |
五、object
- 只有一个实例的类(单例)
- 不能自定义构造方法
- 可以实现接口、继承父类
- 本质上就是单例模式最基本的实现
六、伴生对象与静态成员
- 每个类可以对应一个伴生对象
- 伴生对象的成员全局独一份
- 伴生对象的成员类似Java的静态成员
- 静态成员考虑用包级函数、变量代替
- 使用JvmField和JvmStatic,可以让伴生对象在Java中使用时看起来像静态成员和静态方法
七、方法重载(Overloads)和默认参数
重载
- 写了一个方法和已经存在的方法重名,参数不相同
- Jvm函数签名的概念:函数名、参数列表
- 跟返回值没有关系
默认参数
- 为函数参数设定一个默认值
- 可以为任意位置的参数设置默认值
- 函数调用产生混淆时用具名参数
方法重载与默认参数
- 方法重载与默认参数可以互相转换,在Java中调用有默认参数的方法时,该方法需要使用注解@JvmOverloads
- 避免定义关系不大的重载方法
八、扩展成员(二次加工)
- 为现有类添加方法、属性
fun X.y():Z{...}
val X.m
//注意扩展属性不能初始化,类似接口属性
- Java 调用扩展成员类似调用静态方法
九、属性代理
- 定义方法
val/var <property name>: <Type> by <expression>
- 代理者需要实现相应的setValue/getValue方法
- by lazy 就是在第一次使用的时候才去实例化对象
十、数据类(data class)
- 默认实现 copy()、toString()、equals()等方法
- 编译器默认生成component[1-N]方法,可以自己复写
data class China(val code:Int,name: String)
val (a,b) = China(0,"中国")
pringln("$a -> $b")
- allOpen和noArg 插件解决data class 的类被解析成final类,并且无空构造方法的问题
//build.gradle 中的 dependencies 中添加
dependencies{
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version"
}
//build.gradle 中 添加插件的应用
apply plugin: 'kotlin-noarg'
apply plugin: 'kotlin-allopen'
// 插件的配置
noArg{
annotation("注解类名")
}
allOpen{
annotation("注解类名")
}
- 属性需要写到构造方法,初始化时需要传入参数
十一、内部类
- 定义在类内部的类
- 与类成员有相似的访问控制
- 默认是静态内部类,非静态用 inner 关键字
- this@Outter 与 this@Inner
匿名内部类
- 没有定义名字的类
- 类名编译时生成,类似Outter$1.class
- 可继承父类、实现多个接口,与Java 不一样
十二、枚举类
- 实例可数的类,注意枚举也是类
- 可以修改构造方法,添加成员
- 可以提升代码的表现力,也有一定的性能开销
十二、密封类(sealed class)
- 子类可数的类
- <V1.1,子类必须定义为密封类的内部类
- v1.1开始,子类只需要与密封类在同一个文件中
- 子类可以有多个构造参数
- 表示状态适合使用枚举,需要传输指令时适合使用密封类