【2023】Kotlin教程
第二篇 面向对象与函数式编程
第12章 抽象类与接口
设计良好的软件系统应该具备“可复用性”和“可扩展性”,能够满足用户需求的不断变更。使用抽象类和接口是实现“可复用性”和“可扩展性”重要的设计手段。
12.1 抽象类
Kotlin语言提供了两种类:一种是具体类;另一种是抽象类。前面我们接触的类都是具体类。
12.1.2 抽象类声明和实现
在Kotlin中抽象类和抽象函数的修饰符是abstract,声明抽象类Figure 示例代码如下:
package com.dingjiaxiong
abstract class Figure {
// 绘制几何图形函数
abstract fun onDraw() // 抽象函数
abstract val name: String // 抽象属性
val cname: String = "几何图形" // 具体属性
fun display() {
// 具体函数
println(name)
}
}
在类前面加上abstract修饰符,**这里不使用open修饰符,默认是open。**接着声明了抽象函数,函数前面的修饰符也是abstract, 也不用open 修饰符,默认是open。
抽象函数没有函数体。
abstract val name: String
→ 抽象属性没有初始值,没有setter 和 getter访问器。
val cname: String = "几何图形"
→ 具体属性有初始值或者有setter 或 getter 访问器。
fun display()
是一个具体函数,它有函数体。
【注意】如果一个成员函数或属性被声明为抽象的,那么这个类也必须声明为抽象的。而一个抽象类中,可以有0~n个抽象函数或属性,以及0~n具体函数或属性。
设计抽象类目的就是让子类来实现的,否则抽象就没有任何意义.,举个栗子:
package com.dingjiaxiong
// 几何图形椭圆形
class Ellipse : Figure() {
override val name: String
get() = "椭圆形"
// 绘制几何图形函数
override fun onDraw() {
println("绘制椭圆形...")
}
}
package com.dingjiaxiong
// 三角形
class Triangle(override val name: String) : Figure() {
// 绘制几何图形函数
override fun onDraw() {
println("绘制三角形...")
}
}
这就是两个具体类Ellipse 和 Triangle,它们实现(重写) 了抽象类Figure 的抽象函数onDraw。
Ellipse在类体中实现了name 属性,Triangle在构造函数中提供了name 属性【两种方式最终效果是一样的】,从而实现 父类中Figure 中抽象的name 属性。
调用代码:
package com.dingjiaxiong
fun main() {
// f1 变量是父类类型, 指向实现类实例, 发生多态
val f1: Figure = Triangle("三角形")
f1.onDraw()
f1.display()
// f2 变量是父类类型, 指向实现类实例,发生多态
val f2: Figure = Ellipse()
f2.onDraw()
println(f2.cname)
}
【注意】 抽象类不能被实例化,只有具体类才能被实例化。