一、接口的定义
接口定义的基本语法:
[修饰符] interface 接口名 : 父接口1,父接口2...{
0~N个属性定义...
0~N个方法定义...
0~N个嵌套类、嵌套接口、嵌套枚举定义...
}
- 修饰符可以是public | internal | private中的任意一个,或完全省略修饰符。如果省略了访问控制符,则默认采用public。
- 接口名应与类名采用相同的命名规则。接口名通常使用形容词。
- 一个接口可以有多个直接父接口,但接口只能继承接口,不能继承类。
接口定义的是一种规范,因此接口中不能包含构造器和初始化块定义。
Kotlin接口与Java接口的区别:
- Java接口中的所有成员都会自动使用public修饰,如果为这些成员指定访问权限,也只能指定public访问权限;
- Kotlin接口中的成员可支持private和public两种访问权限。
interface Outputable {
//只读属性定义了getter方法,非抽象属性
val name: String
get() = "输出设备"
//只读属性没有定义getter方法,抽象属性
val brand: String
//读写属性没有定义getter、setter方法,抽象属性
var category: String
//接口中定义的抽象方法
fun out()
fun getDate(msg: String)
//接口中定义的非抽象方法,可使用private修饰
fun print(vararg msgs: String) {
for (msg in msgs) {
println(msg)
}
}
fun test() {
println("接口中的test()方法")
}
}
二、接口的继承
接口的继承和类的继承不一样,接口支持多继承,即一个接口可以有多个直接父接口。
interface InterfaceA {
val propA: Int
get() = 5
fun testA()
}
interface InterfaceB {
val propB: Int
get() = 6
fun testB()
}
interface InterfaceC : InterfaceA, InterfaceB {
val propC: Int
get() = 7
fun testC()
}
三、使用接口
接口不能用于创建实例,但可以用于声明变量。接口的主要用途就是被实现类实现。
接口的主要用途:
- 定义变量,也可用于进行强制类型转换。
- 被其他类实现。
实现接口可以获得所实现接口中定义的属性、方法。
package `0704`
interface Product {
fun getProduceTime(): Int
}
const val MAX_CACHE_LINE = 10
class Printer : Outputable, Product {
private val printData = Array<String>(MAX_CACHE_LINE, { "" })
//用以记录当前需打印的作业数
private var dataNum = 0
//重写接口的抽象只读属性
override val brand: String = "HP"
//重写接口的抽象读写属性
override var category: String = "输出外设"
override fun out() {
//只要还有作业,就继续打印
while (dataNum > 0) {
println("打印机打印:" + printData[0])
//把作业队列整体前移一位,并将剩下的作业数减1
System.arraycopy(printData, 1, printData, 0, --dataNum)
}
}
override fun getDate(msg: String) {
if (dataNum >= MAX_CACHE_LINE) {
println("输出队列已满,添加失败")
} else {
//把打印数据添加到队列里,已保存数据的数量加1
printData[dataNum++] = msg
}
}
override fun getProduceTime(): Int {
return 45
}
}
fun main(args: Array<String>) {
//创建一个Printer对象,当成Output使用
var o: Outputable = Printer()
o.getDate("Kotlin入门")
o.getDate("Kotlin进阶")
o.out()
o.getDate("Kotlin高级")
o.getDate("Kotlin实战")
o.out()
//调用Outputable接口中定义的非抽象方法
o.print("刘备", "关羽", "张飞")
o.test()
//创建一个Printer对象,当成Product使用
val p:Product=Printer()
println(p.getProduceTime())
}
输出结果:
打印机打印:Kotlin入门
打印机打印:Kotlin进阶
打印机打印:Kotlin高级
打印机打印:Kotlin实战
刘备
关羽
张飞
接口中的test()方法
45
接口不能显式继承任何类,但所有接口类型的变量都可以直接赋给Any类型的变量。
四、接口和抽象类
接口和抽象类的相似之处如下:
- 都不能被实例化,都位于继承树的顶端,用于被其他类实现和继承。
- 都可以包含抽象成员,实现接口或继承抽象类的普通子类都必须实现这些抽象成员。
接口和抽象类的差别:
- 接口作为系统与外界交互的窗口,体现的是一种规范。当在一个程序中使用接口时,接口是多模块之间的耦合标准;当在多个应用程序之间使用接口时,接口时多个程序之间的通信标准。
- 抽象类作为系统中多个子类的共同父类,所体现的是一种模板模式设计。
- 接口中不包含构造器;但抽象类中可以包含构造器,抽象类中的构造器并不是用于创建对象的,而是让其子类调用这些构造器来完成属于抽象类的初始化操作。
- 接口中不能包含初始化块;但抽象类中则完全可以包含初始化块。
- 一个类最多只能有一个直接父类,包括抽象类;但一个类可以直接实现多个接口,通过实现多个接口可以弥补Kotlin单继承的不足。
网友评论