1.简单使用
在 Kotlin 中,接口(Interface)是定义了一组抽象方法(没有实现体)的类型,这些方法可以被其他类实现。接口是 Kotlin 中实现多态的重要手段之一。
下面是一个简单的接口定义示例:
interface MyInterface {
fun doSomething()
fun doAnotherThing()
}
这里定义了一个名为 MyInterface 的接口,它包含了两个抽象方法 doSomething 和 doAnotherThing。接口中的所有方法默认都是抽象方法,因此不需要使用 abstract 关键字进行修饰。
要实现一个接口,可以在类声明中使用 : 接口名 的语法。例如:
class MyClass : MyInterface {
override fun doSomething() {
println("Do something")
}
override fun doAnotherThing() {
println("Do another thing")
}
}
这里定义了一个名为 MyClass 的类,它实现了 MyInterface 接口,并实现了 doSomething 和 doAnotherThing 两个方法。注意,在实现接口中的方法时,需要使用 override 关键字进行修饰。
可以通过以下代码使用 MyClass 类:
fun main() {
val obj = MyClass()
obj.doSomething()
obj.doAnotherThing()
}
输出:
Do something
Do another thing
这里创建了一个 MyClass 的实例,并调用了其实现的两个方法。由于 MyClass 实现了 MyInterface 接口,因此可以将 MyClass 实例作为 MyInterface 类型来使用。
2. 接口中的属性
除了方法外,接口中还可以定义属性,它们默认都是抽象的。例如:
interface MyInterface {
val property: Int
}
这里定义了一个名为 MyInterface 的接口,它包含了一个名为 property 的抽象属性。
要实现接口中的属性,可以在实现类中提供一个属性实现。例如:
class MyClass : MyInterface {
override val property: Int
get() = 123
}
这里实现了 MyInterface 接口中的 property 属性,并将其实现为一个只读属性,其值为 123。
3. 接口继承
在 Kotlin 中,一个接口可以继承一个或多个其他接口。例如:
interface MyInterface1 {
fun doSomething()
}
interface MyInterface2 {
fun doAnotherThing()
}
interface MyInterface3 : MyInterface1, MyInterface2 {
fun doMoreThing()
}
这里定义了三个接口,MyInterface1 和 MyInterface2 分别定义了一个方法,MyInterface3 继承了 MyInterface1 和 MyInterface2,并新增了一个方法。
要实现继承了其他接口的接口,可以实现其所有的父接口定义的方法,并在实现类中提供所有继承的属性。例如:
class MyClass : MyInterface3 {
override fun doSomething() {
println("Do something")
}
override fun doAnotherThing() {
println("Do another thing")
}
override fun doMoreThing() {
println("Do more thing")
}
}
这里实现了 MyInterface3 接口,并实现了其继承的所有方法。
4. 接口中的默认方法
在 Kotlin 1.4 及以后的版本中,接口中可以定义默认实现的方法。例如:
interface MyInterface {
fun doSomething()
fun doAnotherThing() {
println("Do another thing")
}
}
这里定义了一个名为 MyInterface 的接口,它包含了一个抽象方法 doSomething 和一个默认实现的方法 doAnotherThing。
要实现接口中的默认方法,可以选择覆盖该方法,也可以直接继承该默认实现。例如:
class MyClass1 : MyInterface {
override fun doSomething() {
println("Do something")
}
// 继承 MyInterface 中的默认实现
}
class MyClass2 : MyInterface {
override fun doSomething() {
println("Do something")
}
override fun doAnotherThing() {
println("Do another thing in MyClass2")
}
}
这里分别实现了 MyInterface 接口的两个类。MyClass1 继承了 MyInterface 中的默认实现,而 MyClass2 覆盖了MyInterface 中的默认实现。
5. 接口中的伴生对象
在 Kotlin 中,一个接口可以包含伴生对象。与类的伴生对象类似,接口的伴生对象是该接口的单例实例。在伴生对象中可以定义属性、方法、扩展函数等。此外,接口的伴生对象也可以实现该接口本身。
一个常见的用途是通过伴生对象提供工厂方法。例如:
interface MyInterface {
companion object {
fun create(): MyInterface = MyInterfaceImpl()
}
fun doSomething()
}
class MyInterfaceImpl : MyInterface {
override fun doSomething() {
println("Doing something")
}
}
fun main() {
val myInterface = MyInterface.create()
myInterface.doSomething()
}
这里定义了一个名为 MyInterface 的接口和一个实现了该接口的类 MyInterfaceImpl。在 MyInterface 的伴生对象中定义了一个名为 create 的方法,用于创建 MyInterface 接口的实现对象。最后在 main 函数中通过 MyInterface.create() 方法创建了一个 MyInterface 实例,并调用了其中的方法。
需要注意的是,在接口中定义伴生对象时,可以省略 companion 关键字。例如:
interface MyInterface {
object Factory {
fun create(): MyInterface = MyInterfaceImpl()
}
fun doSomething()
}
这里使用 object 关键字定义了一个名为 Factory 的伴生对象,用于提供创建 MyInterface 实例的方法。使用时可以直接调用 MyInterface.Factory.create() 方法。
6. 接口代理
在 Kotlin 中,接口代理是一种将接口实例作为属性进行委托的方式,实现了接口的方法调用转发。接口代理常常用于实现多个接口中的部分方法,或者在已有接口实现的基础上新增或修改部分行为。
接口代理可以使用 by 关键字实现,例如:
interface MyInterface {
fun doSomething()
}
class MyInterfaceImpl : MyInterface {
override fun doSomething() {
println("Doing something")
}
}
class MyInterfaceDelegate(private val myInterface: MyInterface) : MyInterface by myInterface {
override fun doSomething() {
println("Doing something else")
}
}
fun main() {
val myInterfaceImpl = MyInterfaceImpl()
val myInterfaceDelegate = MyInterfaceDelegate(myInterfaceImpl)
myInterfaceDelegate.doSomething()
}
这里定义了一个名为 MyInterface 的接口和一个实现了该接口的类 MyInterfaceImpl。接着定义了一个名为 MyInterfaceDelegate 的类,它通过实现 MyInterface 接口并将 myInterface 实例作为属性进行委托,实现了对 MyInterface 接口的代理。最后在 main 函数中创建了一个 MyInterfaceDelegate 实例,并调用了其中的方法。
需要注意的是,通过接口代理实现的方法调用转发,不仅可以在代理类中直接实现对被代理接口的方法的调用,也可以在被代理接口实例中重写被代理方法,然后通过代理类调用该方法。例如:
interface MyInterface {
fun doSomething()
}
class MyInterfaceImpl : MyInterface {
override fun doSomething() {
println("Doing something")
}
}
class MyInterfaceDelegate(private val myInterface: MyInterface) : MyInterface by myInterface {
override fun doSomething() {
println("Doing something else")
}
}
fun main() {
val myInterfaceImpl = MyInterfaceImpl()
val myInterfaceDelegate = MyInterfaceDelegate(myInterfaceImpl)
myInterfaceImpl.doSomething()
myInterfaceDelegate.doSomething()
}
这里创建了一个 MyInterfaceImpl 实例和一个 MyInterfaceDelegate 实例,并分别调用了它们的 doSomething 方法。由于 MyInterfaceDelegate 实现了 MyInterface 接口并将 myInterface 实例作为属性进行委托,所以在 MyInterfaceDelegate 实例中调用 doSomething 方法会被转发到 myInterface 实例的 doSomething 方法。另外,由于 MyInterfaceImpl 实现了 MyInterface 接口并重写了 doSomething 方法,所以直接在 MyInterfaceImpl 实例上调用 doSomething 方法时,会调用 MyInterfaceImpl 中的 doSomething 方法,而不会被代理到 MyInterfaceDelegate 中。