一、面向对象的概念

  • 本质上就是解决如何用程序描述世界的问题
  • 讨论如何把实际存在的东西映射成程序的类和对象
  • 一种程序设计的思路,思想,方法
  • 程序设计层面的概念
  • 设计模式:前人的程序设计经验

二、抽象类与接口

相当于半成品与协议

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开始,子类只需要与密封类在同一个文件中
  • 子类可以有多个构造参数
  • 表示状态适合使用枚举,需要传输指令时适合使用密封类