小狮子的Kotlin学习之路(十)
Kotlin接口这一篇我们了解Kotlin的接口。还记得很早之前看过一篇大神的博客,说接口就是特殊的抽象类,其实我个人也是比较认可这种说法的,尤其是在Kotlin语言中。接口声明语法:interface IfaceName {}。接口默认是open的,因此不需要再open关键字修饰。interfaceKotlinIface{}同样地,在接口中声明的函数,默认也是open...
Kotlin接口
这一篇我们了解Kotlin的接口。还记得很早之前看过一篇大神的博客,说接口就是特殊的抽象类,其实我个人也是比较认可这种说法的,尤其是在Kotlin语言中。
接口声明语法:interface IfaceName {}。
接口默认是open的,因此不需要再open关键字修饰。
interface KotlinIface {
}
同样地,在接口中声明的函数,默认也是open且abstract的。在Idea编辑器中,如果加上open或者abstract,编辑器就会提示多余的修饰符。
接大神博客中的说法,接口就是抽象到类中的所有函数都是抽象的。当然,这还是当年针对Java的描述,在Java8之后,接口也是允许有默认的函数实现的。(这种暴露年龄的话,好像不应该说。。。)
在Kotlin中,接口也是可以有默认的函数实现的。
interface KotlinIface {
fun show(msg: String) // No implementation.
fun read()
fun defaultImpl() { // Default implementation.
show("default show.")
}
}
接口一般仅作为某个对象或者对象群的行为定义的,并不做具体实现。因此,接口必须是有对应的类来做实现的。当然实现也有部分实现和完全实现。
一般地,一个类实现某个接口,就必须实现接口中所有的抽象函数。
class KIfaceImpl : KotlinIface {
override fun show(msg: String) {
}
override fun read() {
}
但是如果实现接口的类是抽象的,即抽象类实现的,则可以实现接口部分需要的函数即可。
abstract class AbsKIfaceImpl : KotlinIface {
override fun show(msg: String) {
}
}
如果实现接口的类是抽象类,则可以选择性的实现接口的零个或全部函数。
类继承是只能继承单个父类的,但是接口却可以同时实现多个接口。这弥补了单继承的缺点。
interface KIface {
fun write()
}
比如我们定义新的接口KIface,让KIfaceImpl同时实现两个接口。
class KIfaceImpl : KotlinIface, KIface {
override fun show(msg: String) {
}
override fun read() {
}
override fun write() {
}
}
我们学习了接口的定义及接口中函数的定义,既然作为一个特殊的抽象类,接口中也是可以定义属性的,但是接口中的属性只能是抽象的,通俗点就是不能赋值的。同样地,和函数一样,默认是open修饰的。
interface KIface {
val name: String
fun write()
}
和函数一样,实现接口的类,必须提供属性的实现。而对于属性来说,就是它get和set方法的实现。
class KIfaceImpl : KIface {
override val name: String
get() = "KIface"
override fun write() {
}
}
一个类实现了某个接口,那这个类也就是这个接口的一个实例。
class KIfaceImpl : KIface {
override val name: String
get() = "KIface impl."
override fun write() {
println("KIface impl write.")
}
}
我们实现了KIface接口并实现了它的属性和函数。我们来运行一下:
fun main() {
val kIface: KIface = KIfaceImpl()
println("name = ${kIface.name}")
kIface.write()
}
在main方法中,我们声明了KIface的对象,但是实际创建的是KIfaceImpl对象。
执行之后的输出结果:

关于Kotlin接口的基本内容就这么多,但是有一个比较特殊的使用场景。比如,我们一个类实现了两个接口,但是两个接口中存在同样的函数声明,那这种情形下,关于函数的实现及调用是什么样子的呢?
interface KIfaceA {
fun a() {
println("KIfaceA -> fun a().")
}
fun b()
}
interface KIfaceB {
fun a() {
println("KIfaceB -> fun a().")
}
fun b() {
println("KIfaceB -> fun b().")
}
}
我们在两个接口中同时有a()函数和函数b(),并且函数声明一样。
我们使用一个类同时实现这两个接口。
class ClassC : KIfaceA, KIfaceB {
override fun a() {
}
override fun b() {
}
}
在这里,虽然两个接口中仅有一个未实现的函数,但是在ClassC中,必须要实现两个函数。

编译器提示,必须重写函数a()因为它继承自多个接口。
class ClassC : KIfaceA, KIfaceB {
override fun a() {
}
override fun b() {
}
}
那问题又来了,我们怎么样调用接口中的默认实现的函数呢?

强大的编译器给我们提示,你需要使用像super<Foo>这样的方式调用。
class ClassC : KIfaceA, KIfaceB {
override fun a() {
super<KIfaceA>.a()
super<KIfaceB>.a()
}
override fun b() {
super.b()
}
}
仔细的同学会注意到,函数b()的调用并没有像函数a()一样,这是因为接口中并不存在两个同样的实现,调用父类的函数时,只能调用已经实现的函数。
下一篇,我们将继续学习一些Kotlin的特殊类。
更多推荐

所有评论(0)