Kotlin面向对象知识点

抽象类与继承

abstract class Person(){
    abstract fun walk()
}

class Child: Person() {
    override fun walk() {
        TODO("Not yet implemented")
    }
}

Kotlin 的类,默认是不允许继承的,除非这个类明确被 open 关键字修饰了。 另外,对于被 open 修饰的普通类,它内部的方法和属性,默认也是不允许重写的,除非它们也被 open 修饰了: 因为Kotlin的类默认是final,编译为Java文件可以看到。在继承的行为上面,Kotlin 和 Java 完全相反。Java 当中,一个类如果没有被 final 明确修饰的话,它默认就是可以被继承的。而这同时也就导致了,在 Java 当中“继承”被过度使用。对于这一点,经典书籍《Effective Java》也有提到过。所以,Java 的继承是默认开放的,Kotlin 的继承是默认封闭的。Kotlin 的这个设计非常好,这样就不会出现 Java 中“继承被滥用”的情况。

接口与实现

interface Car{
    fun run()
}

class RedCar: Car{
    override fun run() {
        TODO("Not yet implemented")
    }
}

Kotlin 的继承和接口实现语法是一样的。 Kotlin 的接口,跟 Java 最大的差异就在于,接口的方法可以有默认实现,同时,它也可以有属性。

interface Car{
    // 接口默认实现
    fun run(){
        if(canRun){
            // do something
        }
    }
    // 接口属性
    val canRun: Boolean
}

class RedCar() : Car{
    // 重写接口属性
    override val canRun: Boolean
        get() = true
}

嵌套类

class Person(){
    val name: String = "张三"

    class innerClass(){
        val a = name; // 报错
    }
}
innerClass中无法访问name属性

Kotlin 当中的普通嵌套类,对应Java中就是静态内部类,无法访问非静态属性,它的本质是静态的。相应地,如果想在 Kotlin 当中定义一个普通的内部类,我们需要在嵌套类的前面加上 inner 关键字。 inner关键字,表示innerClass 是Person 的内部类,可以正常访问属性和方法

class Person(){
    val name: String = "张三"

    inner class innerClass(){
        val a = name;
    }
}

Kotlin 的这种设计非常巧妙。如果你熟悉 Java 开发,你会知道,Java 当中的嵌套类,如果没有 static 关键字的话,它就是一个内部类,这样的内部类是会持有外部类的引用的。可是,这样的设计在 Java 当中会非常容易出现内存泄漏!而大部分 Java 开发者之所以会犯这样的错误,往往只是因为忘记加“static”关键字了。这是一个 Java 开发者默认情况下就容易犯的错。 Kotlin 则反其道而行之,在默认情况下,嵌套类变成了静态内部类,而这种情况下的嵌套类是不会持有外部类引用的。只有当我们真正需要访问外部类成员的时候,我们才会加上 inner 关键字。这样一来,默认情况下,开发者是不会犯错的,只有手动加上 inner 关键字之后,才可能会出现内存泄漏,而当我们加上 inner 之后,其实往往也就能够意识到内存泄漏的风险了。

特殊类

数据类

数据类(Data Class),顾名思义,就是用于存放数据的类。要定义一个数据类,我们只需要在普通的类前面加上一个关键字“data”即可。

data class Person(val name: String, val age: Int)

在 Kotlin 当中,编译器会为数据类自动生成一些有用的方法。它们分别是:equals();hashCode();toString();componentN() 函数;copy()。

密封类

Kotlin 当中的密封类,常常用来表示某种受到限制的继承结构,是更强大的枚举类。 使用 sealed 关键字定义密封类。

sealed class Result<out R> {
    data class Success<out T>(val data: T, val message:String = "") : Result<T>()

    data class Error(val exception: Exception): Result<Nothing>()

    data class Loading(val time:Long = System.currentTimeMillis()): Result<Nothing>()
}
// 调用
fun display(data: Result<Nothing>) = when(data) {
    is Result.Success -> print("success")
    is Result.Error -> print("error")
    is Result.Loading -> print("loading")
}

总结

  • Kotlin的类, 默认是public的
  • Kotlin的类继承语法、接口实现语法, 是完全一样的
  • Kotlin当中的类默认是对继承封闭的,类当中的成员和方法,默认也是无法被重写的。这样设计的好处是避免继承被滥用
  • Kotlin接口可以有成员属性,还可以有默认实现
  • Kotlin的嵌套类默认是静态的, 这种设计可以防止我们无意中出现内存泄漏问题
  • Kotlin独特的数据类,在语法简洁的同时,还为我们提供了丰富的功能
  • 密封类,作为枚举和对象的结合体,帮助我们很好的设计数据模型,支持when表达式完备性。


原文始发于微信公众号(君伟说):Kotlin面向对象知识点

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/115123.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!