Kotlin系列之继承相关修饰符

Kotlin同Java一样也有一些针对类、成员、和方法的修饰符,今天我们先看看和继承相关的几个修饰符。

与继承相关的几个修饰符主要包括finalopenabstractoverride,下面我们通过具体的例子来说说他们的具体使用。

类和方法默认是final的

在Java中,类默认是可以被继承的,方法默认是可以被重写的。除非你将类或者方法使用final关键字进行修饰。但是在Kotlin中,类和方法默认是final的,也就是类默认不能被继承,方法默认不能被重写,比如下面的代码。

Kotlin代码

1
2
3
4
5
class View{
fun getWidth(){

}
}

在上面的这个类和其中的getWidth()方法就默认是使用final修饰的,也就是这个类是不可以被继承的其中的getWidth()方法也是不可被重写的。

使用open开放类和方法

上面说了,一个类默认不能被继承,那怎么才能让其可以被继承呢?那就使用open关键字修饰它,就如下面这样。

Kotlin代码

1
2
3
4
5
6
7
8
9
10
11
//开放类
open class View{
fun getWidth(){

}
}

//继承类
class TextView: View(){

}

如你上面看到的那样,与实现接口类似,都是使用:来表示继承,这里的View()是不是有点奇怪,在上一节的实现接口时是没有()的。这里先简单说一下这是表示父类构造方法,后面我们会详细说。
虽然类可以被继承了,但是由于getWidth()方法还是final的,所以不能被重写。同样使用open修饰方法。

Kotlin代码

1
2
3
4
5
6
7
8
9
10
11
12
13
open class View{
//开放方法重写
open fun getWidth(){

}
}

class TextView: View(){
//重写方法
override fun getWidth(){

}
}

你会注意到,我们在重写时,必须在子类中对那个被我们重写的方法添加override修饰符,这是强制的,否则就会编译错误。
当我们重写了父的方法,在子类中这方法就默认是open的,也就是这个方法可以被重写了,就像下面这样。

Kotlin代码

1
2
3
4
5
6
7
8
9
10
11
12
13
open class TextView: View(){
//被重写的方法默认是open的
override fun getWidth(){

}
}

class ClickableTextView: TextView(){
//可以重写父类的方法
override fun getWidth() {
super.getWidth()
}
}

有时候我们可能在重写了父类的某个方法后,不希望我们的子类可以继续重写我们的方法,其实也是很容易的,只要给方法显式添加final修饰符即可,就如下面这样。

Kotlin代码

1
2
3
4
5
6
open class TextView: View(){
//final修饰后override方法不再可以被重写
final override fun getWidth(){

}
}

abstract声明抽象类和方法

同Java中一样,abstract可以用来声明一个抽象类或者是一个抽象方法。抽象类是不可以被实例化的,抽象方法必须被重写。所以就保证了,只要是被abstract修饰的类和方法,默认就是open的,因为它们的存在本来就是要被用来继承和重写的。就如下面一样。

Kotlin代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//抽象类默认是open的
abstract class Button{
//抽象类中的普通方法默认是fianl的
fun getHeight(){

}

//抽象方法默认是open的
abstract fun setSomething()
}

class ImgButton: Button(){
//抽象方法必须被重写
override fun setSomething() {

}
}

如上面代码中一样,抽象类中的普通方法,默认是final,不能被重写,但是抽象方法默认是open的,而且抽象方法必须要在继承类中被重写,同时必须显式指定override修饰符。

override声明重写的方法

其实override在上面的代码中已经多次出现了,它是Kotlin规定必须对重写的方法显式指定的修饰符,否则会编译出错。其实override还有另一层用法,使用override修饰的方法默认都是open的,可以被后面的子类重写,要是不想被重写,那就必须手动声明final修饰符。由于代码和前面的示例代码一样,这里就不再重复了。

对比总结

这里通过一个表格,简单对比总结一下上面的几种修饰符。

修饰符 对成员方法的要求 备注
final 不能被重写 类中成员默认
open 可以被重写 必须明确指定
abstract 必须被重写 用于抽象类中
override 重写父类或接口中的方法 override修饰的方法默认是open的

写在最后

在这一节,与Java相比,Kotlin貌似增加了许多新的规则和强硬的措施,看似是多余麻烦的,其实这是在改善Java以前存在的一些潜在问题,让Kotlin变成一门安全的语言。

如果博客对您有帮助,不妨请我喝杯咖啡...