开放类与子类
本课属于 Coddy Kotlin 学习旅程的“面向对象编程”单元。第 17 课,共 57 课。
继承允许一个类基于另一个类构建。子类会获得超类的所有属性和方法,还可以添加自己的属性和方法。Kotlin 中的类默认是封闭的,因此必须先将类标记为 open,其他类才能继承它:
open class Animal(val name: String) {
fun describe() = "$name is an animal"
}
class Dog(name: String) : Animal(name) {
fun fetch() = "$name fetches the ball"
}在 main 中:
val rex = Dog("Rex")
println(rex.describe())
println(rex.fetch())输出:
Rex is an animal
Rex fetches the ballclass Dog(name: String) : Animal(name) 表示 Dog 扩展了 Animal,并将 name 传递给超类构造函数。参数没有 val,因为 Animal 中已经存在该属性。不能扩展非 open 类:
class Plant(val name: String)
// class Tree(name: String) : Plant(name) // 错误:此类型是 final,不能被继承
open class Vehicle(val wheels: Int)
class Bike : Vehicle(2) // 传入一个固定值
class Truck(val load: Int) : Vehicle(6) // 添加自己的属性Dog 是一种 Animal,因此在需要超类类型的任何地方,都可以使用子类实例。一个 List<Animal> 可以存放狗、猫和普通动物,并且每个元素都有 Animal 的成员:
open class Animal(val name: String) {
fun describe() = "$name is an animal"
}
class Dog(name: String) : Animal(name)
class Cat(name: String, val indoor: Boolean) : Animal(name)在 main 中:
val pets: List<Animal> = listOf(Dog("Rex"), Cat("Tom", true), Animal("Generic"))
for (p in pets) println(p.describe())输出:
Rex is an animal
Tom is an animal
Generic is an animal继承表示“是一个”的关系:狗是一种动物,储蓄账户是一种账户。当一个类只是使用另一个类时(汽车有一个发动机),应改为给它添加一个该类型的属性。Kotlin 中的类默认是封闭的,因此,只有明确要允许扩展的类才会用 open 标记,其他类都能避免子类改变其行为。
open class Account(val owner: String)
class SavingsAccount(owner: String) : Account(owner) // is-a:继承关系
class Engine(val horsepower: Int)
class Car(val engine: Engine) // has-a:包含一个属性挑战
简单Manager 重复了 Employee 已有的内容。将 Employee 设为开放类,并将 Manager 变成它的子类:Manager(name: String, salary: Int) 将两个值传给 Employee,并且只保留新增的内容,即一个私有列表,用于存储汇报对象的姓名,并提供 addReport(name) 和 teamSize()。在 Employee 中,raise(percent) 按指定百分比提高薪水,结果向下取整;describe() 返回 Ada earns 5500。
提供的代码会根据第一行(name,salary)创建一个经理,将后续每个姓名添加为汇报对象,涨薪 10%,并输出 Ada earns 5500 and leads 2,然后检查经理是否是 Employee。
你的代码应写在 Employee.kt 和 Manager.kt 中。Main.kt 包含提供的输入/输出代码,不能编辑。
亲手试试
fun main() {
// 已提供的输入输出代码:保持原样
val input = generateSequence(::readLine).toList()
val (name, salary) = input[0].split(",")
val boss = Manager(name, salary.toInt())
for (report in input.drop(1)) boss.addReport(report)
boss.raise(10)
println("${boss.describe()} and leads ${boss.teamSize()}")
println("a manager is an employee: ${(boss as Any) is Employee}")
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Kotlin 在线编辑器