一、面向对象的概念
- 本质上就是解决如何用程序描述世界的问题
- 讨论如何把实际存在的东西映射成程序的类和对象
- 一种程序设计的思路、思想、方法
- 程序设计层面的概念
- 设计模式:前人的程序设计经验
二、抽象类与接口
相当于半成品与协议
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开始,子类只需要与密封类在同一个文件中
- 子类可以有多个构造参数
- 表示状态适合使用枚举,需要传输指令时适合使用密封类
网友评论