Kotlin 接口与 Java 8 中的接口类似。它们可以包含抽象方法的定义以及非抽象方法的实现。但是,它们不能包含任何状态。
也就是说,接口可以有属性,但必须是抽象的,或者提供访问器实现。
推荐阅读: Kotlin 抽象类
Kotlin 中的抽象类与接口类似,但有一个重要区别。抽象类的属性不必是抽象的,也不必提供访问器实现。
如何定义接口?
在 Kotlin 中,使用关键字 interface
来定义接口。例如,
interface MyInterface { var test: String // abstract property fun foo() // abstract method fun hello() = "Hello there" // method with default implementation }
这里,
- 创建了一个名为 MyInterface 的接口。
- 该接口有一个抽象属性 test 和一个抽象方法
foo()
。 - 该接口还有一个非抽象方法
hello()
。
如何实现接口?
类或对象可以这样实现接口:
interface MyInterface { val test: Int // abstract property fun foo() : String // abstract method (returns String) fun hello() { // method with default implementation // body (optional) } } class InterfaceImp : MyInterface { override val test: Int = 25 override fun foo() = "Lol" // other code }
这里,类 InterfaceImp 实现了 MyInterface 接口。
该类覆盖了接口中的抽象成员(test 属性和 foo()
方法)。
示例:接口如何工作?
interface MyInterface {
val test: Int
fun foo() : String
fun hello() {
println("Hello there, pal!")
}
}
class InterfaceImp : MyInterface {
override val test: Int = 25
override fun foo() = "Lol"
}
fun main(args: Array<String>) {
val obj = InterfaceImp()
println("test = ${obj.test}")
print("Calling hello(): ")
obj.hello()
print("Calling and printing foo(): ")
println(obj.foo())
}
运行程序后,输出将是
test = 25 Calling hello(): Hello there, pal! Calling and printing foo(): Lol
interface MyInterface {
// property with implementation
val prop: Int
get() = 23
}
class InterfaceImp : MyInterface {
// class body
}
fun main(args: Array<String>) {
val obj = InterfaceImp()
println(obj.prop)
}
运行程序后,输出将是
23
这里,prop 不是抽象的。但是,在接口内部是有效的,因为它提供了访问器的实现。
但是,你不能在接口内部写 val prop: Int = 23
这样的代码。
在类中实现两个或多个接口
Kotlin 不允许真正的 多重继承。但是,可以在单个类中实现两个或多个接口。例如,
interface A {
fun callMe() {
println("From interface A")
}
}
interface B {
fun callMeToo() {
println("From interface B")
}
}
// implements two interfaces A and B
class Child: A, B
fun main(args: Array<String>) {
val obj = Child()
obj.callMe()
obj.callMeToo()
}
运行程序后,输出将是
From interface A From interface B
解决覆盖冲突(多接口)
假设两个接口(A 和 B)有一个同名(例如 callMe()
方法)的非抽象方法。你在一个类(例如 C)中实现了这两个接口。现在,如果你使用类 C 的对象调用 callMe()
方法,编译器将报错。例如,
interface A {
fun callMe() {
println("From interface A")
}
}
interface B {
fun callMe() {
println("From interface B")
}
}
class Child: A, B
fun main(args: Array<String>) {
val obj = Child()
obj.callMe()
}
错误如下:
Error:(14, 1) Kotlin: Class 'C' must override public open fun callMe(): Unit defined in A because it inherits multiple interface methods of it
要解决此问题,你需要提供自己的实现。方法如下:
interface A {
fun callMe() {
println("From interface A")
}
}
interface B {
fun callMe() {
println("From interface B")
}
}
class C: A, B {
override fun callMe() {
super<A>.callMe()
super<B>.callMe()
}
}
fun main(args: Array<String>) {
val obj = C()
obj.callMe()
}
现在运行程序,输出将是:
From interface A From interface B
这里,在类 C 中提供了 callMe()
方法的显式实现。
class C: A, B { override fun callMe() { super<A>.callMe() super<B>.callMe() } }
语句 super<A>.callMe()
调用了类 A 的 callMe()
方法。同样,super<B>.callMe()
调用了类 B
的 callMe()
方法。