OOP相比Java的变化

16 阅读2分钟

Java编程中,每一个文件都是一个类,但是在kotlin中比较灵活,既可以是类文件,也可以是一个单独组织代码的文件。

  1. Class 是面向对象编程的核心,用于封装数据和行为,适合处理复杂的业务逻辑。
  2. File 是代码的物理组织单位,可以包含多个类、顶级函数和变量,适合组织代码和编写小型工具。

todo 打上双链kotlin的设计哲学

没有new关键字

在Java开发中,创建一个对象需要new一个对象(过年了需要new一个对象😂)。在Kotlin的设计哲学中: 当调用了某个类的构造函数时,你的意图只可能是对这个类进行实例化,因此即使没有new关键字,也能清晰表达出你的意图

// 定义一个类
class Person {
    var name = ""
    var age = 0
    fun eat() = println("${this.name} eating. He is ${age} years old")
}

创建一个对象不需要new,直接调用类的构造方法

fun main() {
    // 直接调用类的构造方法进行创建对象
    val person = Person()
    person.name = "Pkmer"
    person.age = 18
    person.eat()
}

继承

《Effective Java》这本书中明确提到,如果一个类不是专门为继承而设计的,那么就应该主动将它加上final声明,禁止它可以被继承。Kotlin在设计的时候遵循了这条编程规范,默认所有非抽象类都是不可以被继承的包括其方法不能被重写

// 父类Person.kt
open class Person {
    var name = ""
    var age = 0
    open fun eat() = println("${this.name} eating. He is ${age} years old")
}

Student子类继承父类Person

class Student(val sid:String = "001", val grade: Int = 1)
    : Person() {
        // 如果要重写父类的方法,则父类的方法也必须使用open关键字
        override fun eat() = println("学生${name}正在吃饭")
}

主构造函数与次要构造函数

在上面的代码中Student(val sid:String = "001", val grade: Int = 1)这是Student的主构造函数。有主构造函数,那么就有次构造函数。对比Java就是多个构造函数。

  1. 主构造函数的特点是没有函数体
  2. 次构造函数是通过constructor关键字来定义,并且需要通过this关键字来调用主构造函数。
    1. 注意: 在 Kotlin 中,次构造函数的参数不能使用 valvar 关键字。这些关键字只能用于主构造函数中声明属性次构造函数的参数只是普通的函数参数,不会自动生成类的属性
class Student(val sid: String = "001", val grade: Int = 1) : Person() {

    /**注意
     * 即使主构造中grade中有默认值,次构造函数仍然会报错
     * There's a cycle in the delegation calls chain
     */
    // constructor(sid: String): this(sid){}

    /**修复
     * 明确指定 grade 的值为 1
     */
    constructor(sid: String): this(sid,1){}

    // 如果要重写父类的方法,则父类的方法也必须使用open关键字
    override fun eat() = println("学生${name}正在吃饭")
}

没有主构造函数只有次构造函数super关键字

由于没有主构造函数,在Student子类继承Person父类上自然也不需要声明父类的Person构造函数,此时在子类的次构造函数中通过super来调用父类的构造函数

class Student: Person {
    // 此构造方法通过super调用父类的构造方法
    constructor(sid: String): super(){}
    // 如果要重写父类的方法,则父类的方法也必须使用open关键字
    override fun eat() = println("学生${name}正在吃饭")
}

private constructor升级为主构造函数

class User private constructor(val name: String) {
 // ... 结合伴生对象来创建User的对象
}

扩展

标题
kotlin中的可见性
密封类(Sealed Class)