抽象类与继承
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