抽象类
一个类和它的一些成员可以声明为abstract。类中抽象的成员没有实现。需要注意的是,我们不需要用open显式注解抽象类或函数。
我们可以用一个非抽象的open函数覆写一个抽象的函数。
open class Base {
open fun f() {
}
}
abstract class Derived : Base() {
override abstract fun f()
}
接口
Kotlin中的接口和Java 8中的类似。它们可以包含抽象方法的声明,或者实现也可以。和抽象类的区别在于接口不能保存状态。它们可以具有属性,但这些需要是抽象的或提供访问器实现。
接口的定义使用关键字interface
interface MyInterface{
fun bar()
fun foo(){
println("MyInterface.foo")
}
}
实现接口
一个类或对象可以实现一个或多个接口。
class ChildOfInterface : MyInterface {
override fun bar() {
foo()
}
override fun foo() {
super.foo()
println("ChildOfInterface.foo")
}
}
接口中的属性
接口中是可以声明属性的。接口中的声明既可以是抽象的,也可以提供getter和setter。接口中的属性不能有后备字段,因此接口中的getter或setter不能引用它们。
interface MyInterface {
val prop: Int //抽象的
val propertyWithImplementation: String
get() = "abc"
fun bar()
fun foo() {
println("MyInterface.foo")
}
}
class ChildOfInterface : MyInterface {
override val prop: Int
get() = 3
override fun bar() {
foo()
}
override fun foo() {
super.foo()
println("ChildOfInterface.foo")
}
}
也就是说接口的定义的属性默认也是要覆写的,如果不想子类覆写,那么需要提供get()设置值,并且只能使用get()来提供初始值。
解决覆写冲突
当我们继承了很多父类时,可能会出现继承了同一个方法的多个实现。举个例子:
interface A {
fun foo() {
println("A")
}
fun bar()
}
interface B {
fun foo() {
println("B")
}
fun bar() {
println("bar")
}
}
class C : A {
override fun bar() {
println("C.bar")
}
}
class D : A, B {
override fun foo() {
super<A>.foo()
super<B>.foo()
println("D.foo")
}
override fun bar() {
super<B>.bar()
}
}
fun main(args: Array<String>) {
var d = D()
d.foo()
d.bar()
}
这个在继承中有讲到,这儿就不赘述了。