Kotlin系列之接口

今天说说Kotlin中的接口。

还是同样的,在说Kotlin中的接口之前先来说说Java中的接口。然后对比着来学习。

Java中的接口

先上一段代码吧,然后再总结一下Java中的接口的一些相关知识点。

Java代码

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface Clickable {
String mFlag = "flag";
int count = 10;

void click();
}

public class Button implements Clickable{
@Override
public void click() {
System.out.println(mFlag + " 点击了 " + count);
}
}

上面几行代码包含了如下的知识点:
1 . 使用interface关键字声明一个接口
2 . 接口中的成员变量都是常量,也就是默认的修饰符是public static final类型的
3 . 接口中的成员方法都是抽象方法,默认的修饰符是public abstract,抽象方法没有方法体
4 . 接口是可以多继承
5 . 一个类使用implements来实现接口, 一个类可以实现多个接口,实现接口的类要么声明为抽象类,要么就要全部实现接口中的方法
6 . 接口没有构造方法,所以不能被实例化
上面这几点都是Java的基础知识点,这里就不再赘述,主要是写出来便于与后面Kotlin接口的规则做对比。

Kotlin中的接口

Kotlin中的接口有部分语法与Java接口是类似的,但还是存在一些差异。下面看看上面的Java代码的Kotlin的写法。

Kotlin代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package kt

interface Clickable{
fun click()

fun touch() = println("你触摸了")
}

package kt

class Button: Clickable{
override fun click() {
println("点击了。。。")
touch()
}
}

对比前面的Java代码,先主要说一下这几点差异。
1 . Kotlin中的默认访问修饰符是public,所以这里直接省略了
2 . Kotlin中也是使用interface关键字来声明一个接口
3 . Kotlin接口中的方法可以没有方法体,也可以为其提供一个默认的方法实现,就像上面的touch方法
4 . Kotlin中使用:接口名来实现一个接口
5 . Kotlin中必须在实现了接口的方法前加override关键字,这是强制要求,否则不能编译。在Java中的@Override注解是可以省略的。

通过以上对比,我们发现Kotlin中对于一些我们可能会犯错的地方做了强制要求,然后增强了接口的能力,增加了方法的默认实现功能。

上面是Kotlin中实现一个接口的例子,下面我们再来看看多个接口的复杂情况。

Kotlin代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
interface Clickable{
fun on() = println("我是点击开关")

fun click()
}

interface Touchable{
fun on() = println("我是触摸开关")
}

class Button: Clickable, Touchable{
override fun on() {
super<Clickable>.on()
super<Touchable>.on()
}

override fun click() {
println("点击了。。。")
}
}

我们知道,如果一个类实现了两个接口,如果这两个接口中有同名的抽象方法,那我们只需要实现一个方法就可以了,反正两个方法都没有方法体。
但是在Kotlin中引入了抽象方法默认实现,这时候如果两个方法名相同,就像上面的Clickable接口和Touchable接口中都有on这个抽象方法的默认实现,这时候一个类同时实现这两个接口会怎么样呢。
这时候,由于Kotlin也不知道到底该使用哪种默认实现,这时候就冲突了,那就直接强制要求我们必须重写实现这个冲突的方法。
还有一种情况是我们可能需要在具体类中调用一下我们实现的接口中的默认实现方法,那如果方法名相同,我们怎么调用呢?
就像上面写的那样,我们使用super<接口名>.方法名,通过指定具体的接口名来调用指定的方法。

Java实现Kotlin的接口

说完了Kotlin中的接口,那我么就要考虑一下Java和Kotlin的互操作了,那我们在Kotlin中定义的接口如何在Java中实现呢,尤其是对于Kotlin中的抽象方法默认实现这种情况怎么处理呢?看看下面的代码。

Kotlin代码

1
2
3
4
5
6
7
8
9
interface Touchable{
fun on() = println("我是触摸开关")
}

interface Clickable{
fun on() = println("我是点击开关")

fun click()
}

Java代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class JavaImpl implements Touchable, Clickable{
@Override
public void click() {

}

@Override
public void on() {
//调用默认的方法实现
Clickable.DefaultImpls.on(this);
Touchable.DefaultImpls.on(this);
}

public static void main(String[] args) {
JavaImpl java = new JavaImpl();
java.on();
}
}

可以看出,在Java中直接就要求实现冲突的默认方法。并且提供了接口名.DefaultImpls.方法名(this)这种调用方法允许我们调用Kotlin中定义的默认方法实现。

写在最后

通过上面的对比,我们发现Kotlin提供了更加灵活的接口使用,同时还提供了良好的与Java的互操作性,让我们可以写出更加优雅灵活的代码。

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