抽象类
类以及其中的某些成员可以声明为abstract
表示是抽象类。
/** 父类 */
open class Machine {
open fun name(){
}
}
/** 抽象类 */
abstract class Mobilephone : Machine(){
//强制子类实现
abstract override fun name();
}
注意:抽象类是不可实例化的,必须由子类实现,因此抽象类不需要用open
修饰。
接口
Kotlin接口可以即包含抽象方法的声明也包含实现。与抽象类不同的是,接口无法保存状态。它可以有属性但必须声明为抽象或提供访问器实现。
使用关键字interface
来定义一个接口:
interface A {
//有函数体的函数
fun foo() {
println("A##foo")
}
//待实现的函数
fun bar()
}
实现接口
一个类可以实现一个或者多个接口。
class C : A {
//实现接口A的方法
override fun bar() {
print("C##bar")
}
}
接口中的属性
你可以在接口中定义属性。在接口中声明的属性要么是抽象的,要么提供访问器的实现。在接口中声明的属性不能有幕后字段(backing field),因此接口中声明的访问器不能引用它们,否则会提示错误。
interface Named {
//抽象属性
val name: String
//提供访问器的实现
val simpleName: String
get() = ""
fun foo() {
print(name)
}
}
使用幕后字段报错,如下图:
接口继承
一个接口可以从其他接口派生,从而既提供基类成员的实现也声明新的函数和属性。很自然的,实现这样接口的类只需定义所缺少的实现:
interface Person : Named {
val firstName : String
val lastName : String
override val name: String
get() = "$firstName _ $lastName"
fun log() {
print(name)
}
}
//数据类Employee
data class Employee(
//只实现需要实现的,不必实现name
override val firstName: String,
override val lastName: String,
val pos: Int)
: Person {
}
解决覆盖冲突
实现多个接口时,可能会遇到同一方法继承多个实现的问题。
//接口A
interface A {
fun foo() {
println("A##foo")
}
fun bar()
fun a(){
}
}
//接口B
interface B {
fun foo() {
println("B##foo")
}
fun bar() {
println("B##bar")
}
fun b(){
}
}
//接口D
class D : A, B {
override fun foo() {
//选择实现
super<A>.foo()
super<B>.foo()
//也可以自己处理逻辑,不调用父类
}
override fun bar() {
//因为A的bar未实现,所以这里调用super只能调用B,所以没有声明泛型
super.bar()
//也可以自己处理逻辑,不调用父类
}
}
如上我们从 A 和 B 派生 D,我们需要实现我们从多个接口继承的所有方法
,实现的方法具体执行什么代码逻辑可由我们自己决定。
这里我总结一下:
- 接口中抽象的方法是一定需要实现的,如上面的
bar()
。 - 如果继承的多个接口拥有相同的方法,如上面
foo()
,是一定需要实现的。 - 其他父类的方法如
a() 或者 b()
可由我们自己决定是否需要实现。
上一篇:Kotlin学习历程——继承
下一篇:Kotlin学习历程——扩展