文章目录
定义
我们日常生活中接触的接口常见的有 Type-C 接口、USB 接口。我们可以看到,带上了接口,可以用于与特定的设备连接,实现充电、存储等功能。
我们使用interface
定义一个接口,其写法与定义类相似:
kt
interface USB
我们可以给它取个名字,因为该名字是所有USB
共有的,我们可以放到伴生对象中(因为后面有一些小动作,还是把伴生对象先删掉):
kt
interface USB {
companion object {
const val NAME = "USB"
}
}
Note:接口没有构造函数,你不能为一个接口声明构造。
抽象属性
我们知道,USB 接口是存在版本的,我们可以给USB
定义一个version
。如果你对version
赋值,IDEA 提示Property initializers are not allowed in interfaces
(interface
中属性初始化是不被允许的),因为此时的version
是抽象属性。
如果在属性或方法定义前加上关键字abstract
,可以将其声明为抽象属性或方法。此时属性不能被赋值,而方法不能拥有方法体。抽象会在实现类(继承自该接口的类)中被实现(override
),类似下方提到的默认方法。
kt
interface USB {
// 此处 abstract 可以省略
val version: String
}
Note:接口中不允许初始化属性,但是可以使用
get
函数(Getter),此时该属性不 是abstract
抽象属性,是open
的(可被实现类override
重写):
ktinterface USB { // open 可省略 open val version: String get() = "3.0" }
抽象方法
使用 USB 接口的工具有很多的用途,我们并不知道它具体用来干什么,此时,我们可以给USB
定义一个实现某种功能(如充电、存储)的抽象函数。定义抽象方法时不需要写方法体(也就是不需要说明它要拿来干什么)。方法体会在实现类中写出。
kt
interface USB {
val version: String
// 此处 abstract 被省略
fun work()
}
默认方法
接口中可以写一些具有方法体的方法,其默认带有open
修饰符(可以被实现类更改方法体)。
kt
interface USB {
val version: String
fun work()
// 此处 open 被省略
fun link() = print("连接")
}
使用伴生对象实现接口
还记得伴生对象companion object
是可以继承的吗(继承与实现其实是差不多的意思)?我们可以让伴生对象实现我们定义的USB
(在 Kotlin 中,实现接口使用: 被实现接口, ...
):
kt
interface USB {
val version: String
fun work()
// 此处 open 被省略
fun link() = print("连接")
companion object: USB {
}
}
此时会发现object
有红色下划线,我们将光标移动到它的位置,鼠标在这暂停一段时间便会出现提示,我们需要点击实现成员(此功能也可以在光标在object
上时,按下键盘上的Alt
+Enter(回车)
唤出),在新弹窗中点击确定。
接着我们便会看到生成的代码,可以看到重写的部分使用了override
修饰:
kt
interface USB {
val version: String
fun work()
// 此处 open 被省略
fun link() = println("连接")
companion object: USB {
override val version: String
get() = TODO("Not yet implemented")
override fun work() {
TODO("Not yet implemented")
}
}
}
我们需要稍加修改:
kt
interface USB {
val version: String
fun work()
// 此处 open 被省略
fun link() = println("连接")
companion object: USB {
override val version = "3.0"
override fun work() {
print("充电")
}
}
}
此时,伴生对象便实现了USB
。我们可以让它做点事情:
kt
fun main() {
// 或者是 USB.Companion.version
println(USB.version)
USB.link()
USB.work()
}
3.0
连接
充电
我们还可以重写默认方法link
,此时就会盖掉默认方法:
kt
interface USB {
val version: String
fun work()
fun link() = println("连接")
companion object: USB {
override val version = "3.0"
override fun work() {
print("充电")
}
// 重写 link
override fun link() {
println("连接电脑")
}
}
}
fun main() {
println(USB.version)
USB.link()
USB.work()
}
3.0
连接电脑
充电
实例化接口
接口实例化与类不同,需要使用object
关键字,并且需要重写抽象属性或方法:
kt
interface USB {
val version: String
}
fun main() {
val usb = object : USB {
override val version = "3.0"
}
print(usb.version)
}
3.0
这其实很好理解,因为我们可以使用object
声明一个Any
类型的对象,在此基础上像伴生对象那样实现USB
就行了:
fun main() {
val myObject: Any = object {}
}