在 Kotlin 中实现接口
Kotlin 中的接口可以包含抽象方法的声明以及方法实现。它们与抽象类的不同之处在于接口不能存储状态。它们可以具有属性,但这些属性需要是抽象的或提供访问器实现。
基本界面
Kotlin 接口包含抽象方法的声明和默认方法实现,尽管它们不能存储状态。
interface MyInterface {
fun bar()
}
这个接口现在可以由一个类来实现,如下所示:
class Child : MyInterface {
override fun bar() {
print("bar() was called")
}
}
与默认实现的接口
Kotlin 中的接口可以具有函数的默认实现:
interface MyInterface {
fun withImplementation() {
print("withImplementation() was called")
}
}
实现此类接口的类将能够使用这些功能而无需重新实现
class MyClass: MyInterface {
// No need to reimplement here
}
val instance = MyClass()
instance.withImplementation()
特性
默认实现也适用于属性 getter 和 setter:
interface MyInterface2 {
val helloWorld
get() = "Hello World!"
}
接口访问器实现不能使用支持字段
interface MyInterface3 {
// this property won't compile!
var helloWorld: Int
get() = field
set(value) { field = value }
}
多种实现
当多个接口实现同一个函数,或全部定义一个或多个实现时,派生类需要手动解析正确的调用
Kotlin
interface A {
fun notImplemented()
fun implementedOnlyInA() { print("only A") }
fun implementedInBoth() { print("both, A") }
fun implementedInOne() { print("implemented in A") }
}
interface B {
fun implementedInBoth() { print("both, B") }
// only defined
fun implementedInOne()
}
class MyClass: A, B {
override fun notImplemented() { print("Normal implementation") }
// implementedOnlyInA() can by normally used in instances
// class needs to define how to use interface functions
override fun implementedInBoth() {
super.implementedInBoth()
super.implementedInBoth()
}
// even if there's only one implementation,
// there multiple definitions
override fun implementedInOne() {
super.implementedInOne()
print("implementedInOne class implementation")
}
}
Kotlin
interface MyInterface {
// abstract
val property: Int
val propertyWithImplementation: String
get() = "foo"
fun foo() {
print(property)
}
}
class Child : MyInterface {
override val property: Int = 29
}
Kotlin
interface FirstTrait {
fun foo() { print("first") }
fun bar()
}
interface SecondTrait {
fun foo() { print("second") }
fun bar() { print("bar") }
}
class ClassWithConflict : FirstTrait, SecondTrait {
override fun foo() {
// delegate to the default
// implementation of FirstTrait
super.foo()
// delegate to the default
// implementation of SecondTrait
super.foo()
}
// function bar() only has a default implementation
// in one interface and therefore is ok.
}
接口中的属性
您可以在接口中声明属性。由于接口不能声明,您只能将属性声明为抽象或为访问器提供默认实现。
科特林
interface MyInterface {
// abstract
val property: Int
val propertyWithImplementation: String
get() = "foo"
fun foo() {
print(property)
}
}
class Child : MyInterface {
override val property: Int = 29
}
使用默认实现实现多个接口时的冲突
当实现多个具有包含默认实现的同名方法的接口时,编译器应该使用哪个实现是模棱两可的。在发生冲突的情况下,开发人员必须覆盖冲突的方法并提供自定义实现。该实现可以选择委托给默认实现或不委托给默认实现。
科特林
interface FirstTrait {
fun foo() { print("first") }
fun bar()
}
interface SecondTrait {
fun foo() { print("second") }
fun bar() { print("bar") }
}
class ClassWithConflict : FirstTrait, SecondTrait {
override fun foo() {
// delegate to the default
// implementation of FirstTrait
super.foo()
// delegate to the default
// implementation of SecondTrait
super.foo()
}
// function bar() only has a default implementation
// in one interface and therefore is ok.
}
超级关键字
interface MyInterface {
fun funcOne() {
// optional body
print("Function with default implementation")
}
}
Note:
If the method in the interface has its own default implementation, we can use the super keyword to access it.
super.funcOne()