美文网首页
Kotlin——面向对象编程

Kotlin——面向对象编程

作者: 四喜汤圆 | 来源:发表于2020-04-18 23:46 被阅读0次

    一、作用

    二、概念

    1. 类与对象

    类是对事物的一种封装,可以拥有属性和行为。
    (1)定义类
    class关键字

    class Person {
        var name = ""
        var age = 0
    
        fun eat() {
            println(name + " is eating. He is " + age + " years old.")
        }
    }
    

    (2)创建对象
    当你调用某个类的构造函数时,你的意图只可能是对这个类进行实例化,即使没有new关键字,也能清晰表达出你的意图。Kotlin 本着最简化的设计原则,将诸如new行尾分号都取消掉了。

    fun testClass() {
        val p = Person()
        p.name = "hello"
        p.age = 10
        p.eat()
    }
    

    2.继承与构造函数

    比如要定义一个Student类,每个学生都有自己的学号和年级,因此我们可以在Student类中加入snograde字段。

    但同时学生也是人,学生也会有姓名、年龄,也需要吃饭。

    这个时候:可以让Student去继承Person

    (1)定义Person
    在 Kotlin 中任何一个非抽象类默认都是不可被继承的。这所以这么设计,类似于val,因为类和变量一样,他们最好都是不可变的,一个类如果允许被继承的话,它无法预知子类会如何实现,可能产生一些未知的风险。

    抽象类本身是无法创建实例的,一定要由子类去继承它才能创建实例,因此抽象类必须可以被继承才行。

    open关键字让该类允许继承

    open class Person {
        var name = ""
        var age = 0
    
        fun eat() {
            println(name + " is eating . He is " + age + " years old.")
        }
    }
    

    (2)创建Student类继承Person

    class Student(val sno: String, val grade: Int) : Person() {
        init {
            println("sno is " + sno)
            println("grade is " + grade)
        }
    }
    

    3. 主构造函数和次构造函数

    Kotlin 中构造函数分为主构造函数和次构造函数。任何一个类只能有一个主构造函数(或没有),可以有多个次构造函数。

    (1)主构造函数

    Kotlin 类默认情况下有一个无参的主构造函数,主构造函数没有函数体,也可以显式地声明带参的主构造函数,这样无参的主构造函数就没了。

    主构造函数中声明成valvar的参数将自动称为该类的字段。

    // 带参的主构造函数
    class Student(val sno: String, val grade: Int) : Person() {
        
    }
    

    (2)次构造函数

    Java 的继承特性规定,子类构造函数必须调用父类构造函数,Kotlin 同样遵循这点。【此处的构造函数,即可以是主也可是次,只要是构造函数就行】

    Q:回看下面的Student类,声明了一个主构造函数,但主构造函数并没有函数体,它如何调用父类的构造函数呢?
    A:子类的主构造函数调用父类的哪个构造函数,在继承的时候通过括号来指定。下面这个即表示调用父类的不带参的主构造函数。

    // 带参的主构造函数
    class Student(val sno: String, val grade: Int) : Person() {
        
    }
    

    Kotlin 规定:当一个类中既有主构造函数,又有次构造函数时,所有次构造函数必须调用主构造函数(包括间接调用)。

    open class Person(val name: String, val age: Int) {
        fun eat() {
            println(name + " is eating. He is " + age + " years old.")
        }
    }
    
    class Student(val sno: String, val grade: Int, name: String, age: Int) : Person(name, age) {
    
        constructor(name: String, age: Int) : this("", 0, name, age)
    
        constructor() : this("", 0)
    }
    
    【证明:】
    当`Student`类中有主构造函数和次构造函数时
    
    Kotlin 要求次构造函数必须调用主构造函数
    
    & Student(val sno: String, val grade: Int, name: String, age: Int) : Person(name, age) 这样的声明方式,使得`Student`类的主构造函数一定会调用父类 Person 的主构造函数
    
    所以:Student 的所有构造函数都会调用父类的主构造函数。『Java 的继承特性规定子类构造函数必须调用父类构造函数』,这个规定得到满足
    

    当一个类没有显式地定义主构造函数且定义了次构造函数时,那这个类中就没有主构造函数。

    // 子类构造函数中必须调用父类的构造函数
    // Teacher 类中没有主构造函数,所以继承 Person 类的时候也就不需要加上括号了
    class Teacher : Person {
        constructor(name: String, age: Int) : super(name, age)
    }
    
    【证明:】
    当`Teacher`类中只有次构造函数时
    
    Kotlin 要求次构造函数必须调用主构造函数
    
    constructor(name: String, age: Int) : super(name, age) 这样的方式,使得这个次构造函数一定会调用父类 Person 的主构造函数
    
    所以:Teacher 的所有构造函数都会调用父类的主构造函数。『Java 的继承特性规定子类构造函数必须调用父类构造函数』,这个规定得到满足
    

    4.接口

    (1)override
    Kotlin 通过上述关键字来重写父类或实现接口中的函数。

    open class Person(val name: String, val age: Int) {
    
    }
    
    interface Study {
        fun readBooks()
        fun doHomework()
    }
    
    class Student(val sno: String, val grade: Int, name: String, age: Int) : Person(name, age), Study {
        override fun readBooks() {
            println(name + " is readBooks")
        }
    
        override fun doHomework() {
            println(name + " is doHomework")
        }
    }
    

    (2)Kotlin 允许对接口中的函数提供默认实现

    interface Study {
        fun readBooks()
        fun doHomework() {
            println("do homework defalut implementation")
        }
    }
    
    class Student(val sno: String, val grade: Int, name: String, age: Int) : Person(name, age), Study {
        override fun readBooks() {
            println(name + " is readBooks")
        }
    }
    

    5.数据类与单例类

    (1)data关键字
    在一个类前面声明data关键字,就标明你希望这个类是一个数据类,Kotlin 会根据主构造函数中的参数帮我们将equals()hashCode()toString()等固定且无实际逻辑意义的方法自动生成。

    data class CellPhone(val brand: String, val price: Double) {
    
    }
    

    【简化】

    // 当一个类没有任何代码时,可以将大括号省略
    data class CellPhone(val brand: String, val price: Double) 
    

    (2)object关键字

    object Singleton {
        fun singletonTest() {
            println("this is a singleton.")
        }
    }
    

    调用方法

    fun testSingleton() {
        Singleton.singletonTest()
    }
    

    四、参考文献

    Java面向对象三大特性

    相关文章

      网友评论

          本文标题:Kotlin——面向对象编程

          本文链接:https://www.haomeiwen.com/subject/zdurmhtx.html