继承和多态
概述
继承和多态是面向对象编程的核心概念。Kotlin提供了强大而灵活的继承机制,支持类继承、接口实现、抽象类等。本章将详细介绍Kotlin中的继承体系、多态性以及相关的最佳实践。
类继承基础
基本继承语法
kotlin
// 基类(父类)
open class Animal(val name: String, val species: String) {
// 属性
var age: Int = 0
protected var health: Int = 100
// 方法
open fun eat(food: String) {
println("$name 正在吃 $food")
health += 5
}
open fun sleep() {
println("$name 正在睡觉")
health += 10
}
// 不能被重写的方法
fun getInfo(): String {
return "$name 是一只 $species,年龄 $age 岁,健康值 $health"
}
// 虚方法(必须被子类重写)
open fun makeSound() {
println("$name 发出声音")
}
}
// 派生类(子类)
class Dog(name: String) : Animal(name, "犬科动物") {
// 子类特有属性
var breed: String = "未知品种"
// 重写父类方法
override fun makeSound() {
println("$name 汪汪叫")
}
override fun eat(food: String) {
println("$name 狼吞虎咽地吃 $food")
health += 8 // 狗吃东西恢复更多健康值
}
// 子类特有方法
fun wagTail() {
println("$name 摇尾巴")
}
fun fetch(item: String) {
println("$name 去捡 $item")
}
}
class Cat(name: String) : Animal(name, "猫科动物") {
var isIndoor: Boolean = true
override fun makeSound() {
println("$name 喵喵叫")
}
override fun sleep() {
println("$name 蜷缩着睡觉")
health += 15 // 猫睡觉恢复更多健康值
}
fun purr() {
println("$name 发出呼噜声")
}
fun climb() {
println("$name 爬到高处")
}
}
fun main() {
println("=== 基本继承示例 ===")
// 创建对象
val dog = Dog("旺财")
dog.breed = "金毛"
dog.age = 3
val cat = Cat("咪咪")
cat.age = 2
cat.isIndoor = true
// 使用继承的方法
println(dog.getInfo())
dog.eat("狗粮")
dog.makeSound()
dog.wagTail()
dog.fetch("球")
println()
println(cat.getInfo())
cat.eat("猫粮")
cat.makeSound()
cat.purr()
cat.sleep()
// 多态性演示
println("\n=== 多态性演示 ===")
val animals: List<Animal> = listOf(dog, cat)
animals.forEach { animal ->
println("处理动物: ${animal.name}")
animal.makeSound() // 调用各自重写的方法
animal.eat("通用食物")
println()
}
}构造函数继承
kotlin
// 父类有多个构造函数
open class Vehicle(val brand: String, val model: String) {
var year: Int = 0
var color: String = "白色"
// 次构造函数
constructor(brand: String, model: String, year: Int) : this(brand, model) {
this.year = year
}
constructor(brand: String, model: String, year: Int, color: String) : this(brand, model, year) {
this.color = color
}
open fun start() {
println("$brand $model 启动")
}
open fun getDescription(): String {
return "$year年 $color $brand $model"
}
}
// 子类继承并扩展构造函数
class Car(brand: String, model: String, val doors: Int) : Vehicle(brand, model) {
var fuelType: String = "汽油"
// 调用父类的次构造函数
constructor(brand: String, model: String, doors: Int, year: Int) : this(brand, model, doors) {
this.year = year
}
constructor(brand: String, model: String, doors: Int, year: Int, color: String, fuelType: String)
: this(brand, model, doors, year) {
this.color = color
this.fuelType = fuelType
}
override fun start() {
println("汽车 $brand $model 点火启动")
}
override fun getDescription(): String {
return "${super.getDescription()},${doors}门,燃料类型:$fuelType"
}
fun honk() {
println("$brand $model 按喇叭:嘀嘀!")
}
}
class Motorcycle(brand: String, model: String, val engineSize: Int) : Vehicle(brand, model) {
var hasWindshield: Boolean = false
constructor(brand: String, model: String, engineSize: Int, year: Int, hasWindshield: Boolean)
: this(brand, model, engineSize) {
this.year = year
this.hasWindshield = hasWindshield
}
override fun start() {
println("摩托车 $brand $model 踩启动杆")
}
override fun getDescription(): String {
val windshield = if (hasWindshield) "有挡风玻璃" else "无挡风玻璃"
return "${super.getDescription()},${engineSize}cc引擎,$windshield"
}
fun wheelie() {
println("$brand $model 做后轮着地特技")
}
}
fun main() {
println("=== 构造函数继承示例 ===")
// 使用不同构造函数创建对象
val car1 = Car("丰田", "卡罗拉", 4)
val car2 = Car("本田", "雅阁", 4, 2023)
val car3 = Car("宝马", "X5", 4, 2023, "黑色", "汽油")
val motorcycle1 = Motorcycle("雅马哈", "R1", 1000)
val motorcycle2 = Motorcycle("哈雷", "戴维森", 1200, 2022, true)
// 显示车辆信息
val vehicles = listOf(car1, car2, car3, motorcycle1, motorcycle2)
vehicles.forEach { vehicle ->
println(vehicle.getDescription())
vehicle.start()
// 类型检查和特有方法调用
when (vehicle) {
is Car -> vehicle.honk()
is Motorcycle -> vehicle.wheelie()
}
println()
}
}抽象类和方法
抽象类定义
kotlin
// 抽象类
abstract class Shape(val name: String) {
// 具体属性
var color: String = "黑色"
// 抽象属性
abstract val area: Double
abstract val perimeter: Double
// 具体方法
fun displayInfo() {
println("形状:$name,颜色:$color")
println("面积:${"%.2f".format(area)}")
println("周长:${"%.2f".format(perimeter)}")
}
// 抽象方法
abstract fun draw()
// 开放方法(可以被重写)
open fun move(x: Double, y: Double) {
println("将 $name 移动到 ($x, $y)")
}
}
// 具体实现类
class Circle(val radius: Double) : Shape("圆形") {
override val area: Double
get() = Math.PI * radius * radius
override val perimeter: Double
get() = 2 * Math.PI * radius
override fun draw() {
println("绘制半径为 $radius 的圆形")
}
override fun move(x: Double, y: Double) {
println("圆形滚动到 ($x, $y)")
}
}
class Rectangle(val width: Double, val height: Double) : Shape("矩形") {
override val area: Double
get() = width * height
override val perimeter: Double
get() = 2 * (width + height)
override fun draw() {
println("绘制 ${width}x${height} 的矩形")
}
}
class Triangle(val base: Double, val height: Double, val side1: Double, val side2: Double) : Shape("三角形") {
override val area: Double
get() = 0.5 * base * height
override val perimeter: Double
get() = base + side1 + side2
override fun draw() {
println("绘制底边 $base,高 $height 的三角形")
}
}
// 抽象类的进一步继承
abstract class Polygon(name: String, val sides: Int) : Shape(name) {
// 多边形的通用方法
fun getSides(): Int = sides
// 抽象方法
abstract fun getInteriorAngleSum(): Double
}
class RegularHexagon(val sideLength: Double) : Polygon("正六边形", 6) {
override val area: Double
get() = (3 * Math.sqrt(3.0) / 2) * sideLength * sideLength
override val perimeter: Double
get() = 6 * sideLength
override fun draw() {
println("绘制边长为 $sideLength 的正六边形")
}
override fun getInteriorAngleSum(): Double = (sides - 2) * 180.0
}
fun main() {
println("=== 抽象类示例 ===")
// 创建具体形状对象
val shapes: List<Shape> = listOf(
Circle(5.0).apply { color = "红色" },
Rectangle(4.0, 6.0).apply { color = "蓝色" },
Triangle(3.0, 4.0, 5.0, 5.0).apply { color = "绿色" },
RegularHexagon(3.0).apply { color = "黄色" }
)
// 多态操作
shapes.forEach { shape ->
shape.displayInfo()
shape.draw()
shape.move(10.0, 20.0)
// 特定类型的操作
if (shape is Polygon) {
println("内角和:${shape.getInteriorAngleSum()}度")
}
println()
}
// 计算总面积
val totalArea = shapes.sumOf { it.area }
println("所有形状的总面积:${"%.2f".format(totalArea)}")
}接口实现和多重继承
接口的多重实现
kotlin
// 定义多个接口
interface Flyable {
val maxAltitude: Double
val wingSpan: Double
fun takeOff() {
println("起飞到 $maxAltitude 米高度")
}
fun land() {
println("降落")
}
fun fly() {
println("在 $maxAltitude 米高度飞行,翼展 $wingSpan 米")
}
}
interface Swimmable {
val maxDepth: Double
val swimSpeed: Double
fun dive() {
println("潜水到 $maxDepth 米深度")
}
fun surface() {
println("浮出水面")
}
fun swim() {
println("以 $swimSpeed km/h 的速度游泳")
}
}
interface Walkable {
val walkSpeed: Double
fun walk() {
println("以 $walkSpeed km/h 的速度行走")
}
fun run() {
println("以 ${walkSpeed * 2} km/h 的速度奔跑")
}
}
// 抽象动物类
abstract class WildAnimal(val name: String, val habitat: String) {
abstract fun eat()
abstract fun makeSound()
fun rest() {
println("$name 在 $habitat 休息")
}
}
// 实现多个接口的类
class Duck(name: String) : WildAnimal(name, "湖泊"), Flyable, Swimmable, Walkable {
override val maxAltitude = 1000.0
override val wingSpan = 0.8
override val maxDepth = 5.0
override val swimSpeed = 8.0
override val walkSpeed = 3.0
override fun eat() {
println("$name 吃水草和小鱼")
}
override fun makeSound() {
println("$name 嘎嘎叫")
}
// 可以重写接口的默认实现
override fun fly() {
println("$name 扇动翅膀在水面上飞行")
}
}
class Penguin(name: String) : WildAnimal(name, "南极"), Swimmable, Walkable {
override val maxDepth = 200.0
override val swimSpeed = 25.0
override val walkSpeed = 2.0
override fun eat() {
println("$name 吃鱼和磷虾")
}
override fun makeSound() {
println("$name 发出企鹅叫声")
}
override fun walk() {
println("$name 摇摆着走路")
}
fun slide() {
println("$name 在冰上滑行")
}
}
class Eagle(name: String) : WildAnimal(name, "山区"), Flyable, Walkable {
override val maxAltitude = 5000.0
override val wingSpan = 2.5
override val walkSpeed = 1.0
override fun eat() {
println("$name 捕食小动物")
}
override fun makeSound() {
println("$name 发出鹰啸声")
}
fun hunt() {
println("$name 从高空俯冲捕猎")
}
}
fun main() {
println("=== 多重接口实现示例 ===")
val animals = listOf(
Duck("唐老鸭"),
Penguin("企鹅波波"),
Eagle("雄鹰阿飞")
)
animals.forEach { animal ->
println("=== ${animal.name} ===")
animal.makeSound()
animal.eat()
animal.rest()
// 根据能力进行不同操作
if (animal is Flyable) {
animal.takeOff()
animal.fly()
animal.land()
}
if (animal is Swimmable) {
animal.dive()
animal.swim()
animal.surface()
}
if (animal is Walkable) {
animal.walk()
animal.run()
}
// 特有方法
when (animal) {
is Penguin -> animal.slide()
is Eagle -> animal.hunt()
}
println()
}
// 按能力分组
println("=== 能力分组 ===")
val flyers = animals.filterIsInstance<Flyable>()
val swimmers = animals.filterIsInstance<Swimmable>()
val walkers = animals.filterIsInstance<Walkable>()
println("会飞的动物:${flyers.map { (it as WildAnimal).name }}")
println("会游泳的动物:${swimmers.map { (it as WildAnimal).name }}")
println("会走路的动物:${walkers.map { (it as WildAnimal).name }}")
}多态性深入
方法重写和动态绑定
kotlin
// 基类
open class Employee(val name: String, val id: String) {
open val baseSalary: Double = 50000.0
open fun calculateSalary(): Double {
return baseSalary
}
open fun getJobDescription(): String {
return "普通员工"
}
open fun work() {
println("$name 正在工作")
}
// 模板方法模式
fun dailyRoutine() {
println("=== ${name}的日常工作 ===")
clockIn()
work()
takeBreak()
work()
clockOut()
println("薪资:${"%.2f".format(calculateSalary())}")
println()
}
private fun clockIn() = println("$name 打卡上班")
private fun takeBreak() = println("$name 休息")
private fun clockOut() = println("$name 打卡下班")
}
// 管理者类
class Manager(name: String, id: String, val teamSize: Int) : Employee(name, id) {
override val baseSalary: Double = 80000.0
override fun calculateSalary(): Double {
return baseSalary + (teamSize * 5000) // 团队奖金
}
override fun getJobDescription(): String {
return "管理 $teamSize 人的团队经理"
}
override fun work() {
println("$name 正在管理团队和制定策略")
}
fun holdMeeting() {
println("$name 召开团队会议")
}
}
// 开发者类
class Developer(name: String, id: String, val programmingLanguage: String) : Employee(name, id) {
override val baseSalary: Double = 70000.0
override fun calculateSalary(): Double {
val languageBonus = when (programmingLanguage.lowercase()) {
"kotlin", "scala" -> 10000.0
"java", "python" -> 8000.0
"javascript" -> 6000.0
else -> 5000.0
}
return baseSalary + languageBonus
}
override fun getJobDescription(): String {
return "$programmingLanguage 开发工程师"
}
override fun work() {
println("$name 正在用 $programmingLanguage 编写代码")
}
fun codeReview() {
println("$name 进行代码审查")
}
}
// 设计师类
class Designer(name: String, id: String, val designTool: String) : Employee(name, id) {
override val baseSalary: Double = 60000.0
override fun calculateSalary(): Double {
return baseSalary + 8000 // 创意奖金
}
override fun getJobDescription(): String {
return "使用 $designTool 的UI/UX设计师"
}
override fun work() {
println("$name 正在用 $designTool 设计界面")
}
fun createPrototype() {
println("$name 创建设计原型")
}
}
// 多态性演示类
class Company {
private val employees = mutableListOf<Employee>()
fun hireEmployee(employee: Employee) {
employees.add(employee)
println("雇佣了 ${employee.name},职位:${employee.getJobDescription()}")
}
fun runDailyOperations() {
println("=== 公司日常运营 ===")
employees.forEach { employee ->
employee.dailyRoutine()
}
}
fun calculateTotalPayroll(): Double {
return employees.sumOf { it.calculateSalary() }
}
fun getEmployeesByType(): Map<String, List<Employee>> {
return employees.groupBy { it::class.simpleName ?: "Unknown" }
}
fun promoteEmployee(employee: Employee) {
println("${employee.name} 获得晋升!")
// 在实际应用中,这里可能会创建新的对象或修改属性
}
}
fun main() {
println("=== 多态性演示 ===")
val company = Company()
// 雇佣不同类型的员工
company.hireEmployee(Manager("张经理", "M001", 5))
company.hireEmployee(Developer("李开发", "D001", "Kotlin"))
company.hireEmployee(Developer("王程序", "D002", "Python"))
company.hireEmployee(Designer("陈设计", "DS001", "Figma"))
// 运行日常操作(多态性体现)
company.runDailyOperations()
// 计算总薪资
val totalPayroll = company.calculateTotalPayroll()
println("公司总薪资支出:${"%.2f".format(totalPayroll)}")
// 按类型统计员工
println("\n=== 员工统计 ===")
val employeesByType = company.getEmployeesByType()
employeesByType.forEach { (type, employees) ->
println("$type: ${employees.size} 人")
employees.forEach { employee ->
println(" - ${employee.name}: ${employee.getJobDescription()}")
}
}
// 演示类型检查和转换
println("\n=== 特殊技能展示 ===")
company.getEmployeesByType().values.flatten().forEach { employee ->
when (employee) {
is Manager -> employee.holdMeeting()
is Developer -> employee.codeReview()
is Designer -> employee.createPrototype()
}
}
}密封类和继承
密封类的使用
kotlin
// 密封类定义状态层次结构
sealed class NetworkResult<out T> {
object Loading : NetworkResult<Nothing>()
data class Success<T>(val data: T) : NetworkResult<T>()
data class Error(val exception: Throwable) : NetworkResult<Nothing>()
}
// 密封类定义UI状态
sealed class UiState {
object Idle : UiState()
object Loading : UiState()
data class Content(val data: String) : UiState()
data class Error(val message: String) : UiState()
}
// 密封类定义用户操作
sealed class UserAction {
object Login : UserAction()
object Logout : UserAction()
data class UpdateProfile(val name: String, val email: String) : UserAction()
data class SendMessage(val recipient: String, val message: String) : UserAction()
}
// 使用密封类的服务类
class NetworkService {
fun fetchUserData(userId: String): NetworkResult<User> {
return try {
// 模拟网络请求
Thread.sleep(100)
when (userId) {
"1" -> NetworkResult.Success(User("1", "Alice", "alice@example.com"))
"2" -> NetworkResult.Success(User("2", "Bob", "bob@example.com"))
"error" -> NetworkResult.Error(RuntimeException("用户不存在"))
else -> NetworkResult.Error(RuntimeException("网络错误"))
}
} catch (e: Exception) {
NetworkResult.Error(e)
}
}
fun processNetworkResult(result: NetworkResult<User>): String {
return when (result) {
is NetworkResult.Loading -> "正在加载用户数据..."
is NetworkResult.Success -> "用户数据加载成功:${result.data.name}"
is NetworkResult.Error -> "加载失败:${result.exception.message}"
}
}
}
// UI控制器类
class UiController {
private var currentState: UiState = UiState.Idle
fun updateState(newState: UiState) {
currentState = newState
renderState()
}
private fun renderState() {
val stateDescription = when (currentState) {
is UiState.Idle -> "界面空闲状态"
is UiState.Loading -> "正在加载..."
is UiState.Content -> "显示内容:${currentState.data}"
is UiState.Error -> "错误:${currentState.message}"
}
println("UI状态更新:$stateDescription")
}
fun handleUserAction(action: UserAction) {
println("处理用户操作:${getActionDescription(action)}")
when (action) {
is UserAction.Login -> {
updateState(UiState.Loading)
// 模拟登录过程
Thread.sleep(500)
updateState(UiState.Content("用户已登录"))
}
is UserAction.Logout -> {
updateState(UiState.Content("用户已登出"))
}
is UserAction.UpdateProfile -> {
updateState(UiState.Loading)
// 模拟更新过程
Thread.sleep(300)
updateState(UiState.Content("个人资料已更新"))
}
is UserAction.SendMessage -> {
updateState(UiState.Loading)
// 模拟发送消息
Thread.sleep(200)
if (action.message.isNotBlank()) {
updateState(UiState.Content("消息已发送给 ${action.recipient}"))
} else {
updateState(UiState.Error("消息不能为空"))
}
}
}
}
private fun getActionDescription(action: UserAction): String {
return when (action) {
is UserAction.Login -> "用户登录"
is UserAction.Logout -> "用户登出"
is UserAction.UpdateProfile -> "更新个人资料:${action.name}, ${action.email}"
is UserAction.SendMessage -> "发送消息给 ${action.recipient}: ${action.message}"
}
}
}
data class User(val id: String, val name: String, val email: String)
fun main() {
println("=== 密封类示例 ===")
// 网络服务示例
val networkService = NetworkService()
println("=== 网络请求示例 ===")
val userIds = listOf("1", "2", "error", "timeout")
userIds.forEach { userId ->
println("请求用户 $userId 的数据...")
val result = networkService.fetchUserData(userId)
println(networkService.processNetworkResult(result))
println()
}
// UI控制器示例
println("=== UI状态管理示例 ===")
val uiController = UiController()
val actions = listOf(
UserAction.Login,
UserAction.UpdateProfile("Alice", "alice@newdomain.com"),
UserAction.SendMessage("Bob", "Hello Bob!"),
UserAction.SendMessage("Charlie", ""), // 空消息,会出错
UserAction.Logout
)
actions.forEach { action ->
uiController.handleUserAction(action)
Thread.sleep(100) // 短暂延迟以观察状态变化
println()
}
}实际应用示例
游戏角色系统
kotlin
// 基础角色类
abstract class GameCharacter(
val name: String,
var level: Int = 1
) {
var health: Int = 100
var mana: Int = 50
var experience: Int = 0
abstract val characterClass: String
abstract val primaryAttribute: String
// 基础能力
abstract fun attack(): Int
abstract fun defend(): Int
abstract fun useSpecialAbility(): String
// 通用方法
fun levelUp() {
level++
health += 20
mana += 10
println("$name 升级到 $level 级!")
}
fun gainExperience(exp: Int) {
experience += exp
println("$name 获得 $exp 经验值")
if (experience >= level * 100) {
experience -= level * 100
levelUp()
}
}
fun takeDamage(damage: Int) {
health = maxOf(0, health - damage)
println("$name 受到 $damage 点伤害,剩余生命值:$health")
}
fun heal(amount: Int) {
health = minOf(100 + level * 20, health + amount)
println("$name 恢复 $amount 点生命值,当前生命值:$health")
}
fun isAlive(): Boolean = health > 0
open fun getStats(): String {
return """
|角色:$name ($characterClass)
|等级:$level
|生命值:$health
|魔法值:$mana
|经验值:$experience
|主属性:$primaryAttribute
""".trimMargin()
}
}
// 战士类
class Warrior(name: String) : GameCharacter(name) {
override val characterClass = "战士"
override val primaryAttribute = "力量"
var armor: Int = 10
var weaponDamage: Int = 15
override fun attack(): Int {
val damage = weaponDamage + level * 2
println("$name 挥舞武器攻击,造成 $damage 点伤害!")
return damage
}
override fun defend(): Int {
val defense = armor + level
println("$name 举盾防御,减少 $defense 点伤害")
return defense
}
override fun useSpecialAbility(): String {
if (mana >= 20) {
mana -= 20
val damage = weaponDamage * 2
return "$name 使用【狂暴攻击】,造成 $damage 点伤害!"
}
return "$name 魔法值不足,无法使用特殊技能"
}
fun charge() {
println("$name 发起冲锋!")
weaponDamage += 5
}
}
// 法师类
class Mage(name: String) : GameCharacter(name) {
override val characterClass = "法师"
override val primaryAttribute = "智力"
var spellPower: Int = 20
init {
mana = 100 // 法师有更多魔法值
}
override fun attack(): Int {
if (mana >= 10) {
mana -= 10
val damage = spellPower + level * 3
println("$name 释放魔法弹,造成 $damage 点魔法伤害!")
return damage
} else {
val damage = 5
println("$name 魔法值不足,使用法杖攻击,造成 $damage 点伤害")
return damage
}
}
override fun defend(): Int {
if (mana >= 15) {
mana -= 15
val shield = spellPower
println("$name 释放魔法护盾,减少 $shield 点伤害")
return shield
}
return 0
}
override fun useSpecialAbility(): String {
if (mana >= 30) {
mana -= 30
val damage = spellPower * 3
return "$name 释放【火球术】,造成 $damage 点火焰伤害!"
}
return "$name 魔法值不足,无法释放火球术"
}
fun meditate() {
mana = minOf(100 + level * 10, mana + 25)
println("$name 冥想恢复魔法值,当前魔法值:$mana")
}
}
// 盗贼类
class Rogue(name: String) : GameCharacter(name) {
override val characterClass = "盗贼"
override val primaryAttribute = "敏捷"
var criticalChance: Double = 0.2
var baseDamage: Int = 12
override fun attack(): Int {
val isCritical = Math.random() < criticalChance
val damage = if (isCritical) {
val critDamage = baseDamage * 2 + level * 2
println("$name 发动暴击!造成 $critDamage 点伤害!")
critDamage
} else {
val normalDamage = baseDamage + level
println("$name 快速攻击,造成 $normalDamage 点伤害")
normalDamage
}
return damage
}
override fun defend(): Int {
val dodgeChance = 0.3
return if (Math.random() < dodgeChance) {
println("$name 敏捷闪避,完全避免伤害!")
Int.MAX_VALUE // 表示完全闪避
} else {
println("$name 闪避失败")
0
}
}
override fun useSpecialAbility(): String {
if (mana >= 25) {
mana -= 25
return "$name 使用【影袭】,下次攻击必定暴击!"
}
return "$name 能量不足,无法使用影袭"
}
fun stealth() {
println("$name 进入潜行状态")
criticalChance += 0.3
}
}
// 战斗系统
class BattleSystem {
fun battle(character1: GameCharacter, character2: GameCharacter) {
println("=== 战斗开始:${character1.name} VS ${character2.name} ===")
var round = 1
while (character1.isAlive() && character2.isAlive() && round <= 10) {
println("\n--- 第 $round 回合 ---")
// 角色1攻击
if (character1.isAlive()) {
val damage1 = character1.attack()
val defense2 = character2.defend()
val actualDamage1 = if (defense2 == Int.MAX_VALUE) 0 else maxOf(0, damage1 - defense2)
if (actualDamage1 > 0) {
character2.takeDamage(actualDamage1)
}
}
// 角色2攻击
if (character2.isAlive()) {
val damage2 = character2.attack()
val defense1 = character1.defend()
val actualDamage2 = if (defense1 == Int.MAX_VALUE) 0 else maxOf(0, damage2 - defense1)
if (actualDamage2 > 0) {
character1.takeDamage(actualDamage2)
}
}
round++
}
// 战斗结果
println("\n=== 战斗结束 ===")
when {
!character1.isAlive() && !character2.isAlive() -> println("平局!")
!character1.isAlive() -> {
println("${character2.name} 获胜!")
character2.gainExperience(50)
}
!character2.isAlive() -> {
println("${character1.name} 获胜!")
character1.gainExperience(50)
}
else -> println("战斗超时,平局!")
}
}
}
fun main() {
println("=== 游戏角色系统示例 ===")
// 创建不同类型的角色
val warrior = Warrior("亚瑟王")
val mage = Mage("梅林")
val rogue = Rogue("罗宾汉")
// 显示角色信息
val characters = listOf(warrior, mage, rogue)
characters.forEach { character ->
println(character.getStats())
println("特殊技能:${character.useSpecialAbility()}")
println()
}
// 角色特有技能演示
println("=== 角色特有技能演示 ===")
warrior.charge()
mage.meditate()
rogue.stealth()
println()
// 战斗演示
val battleSystem = BattleSystem()
// 战士 vs 法师
battleSystem.battle(warrior, mage)
// 恢复角色状态
warrior.health = 100
mage.health = 100
println("\n" + "=".repeat(50))
// 法师 vs 盗贼
battleSystem.battle(mage, rogue)
}最佳实践
1. 继承设计原则
kotlin
// 好的继承设计:遵循里氏替换原则
abstract class PaymentProcessor {
abstract fun processPayment(amount: Double): Boolean
// 模板方法
fun executePayment(amount: Double): String {
return if (validateAmount(amount) && processPayment(amount)) {
"支付成功"
} else {
"支付失败"
}
}
protected open fun validateAmount(amount: Double): Boolean {
return amount > 0
}
}
class CreditCardProcessor : PaymentProcessor() {
override fun processPayment(amount: Double): Boolean {
println("处理信用卡支付:$amount")
return true
}
}
class PayPalProcessor : PaymentProcessor() {
override fun processPayment(amount: Double): Boolean {
println("处理PayPal支付:$amount")
return true
}
override fun validateAmount(amount: Double): Boolean {
return super.validateAmount(amount) && amount <= 10000 // PayPal限额
}
}2. 组合优于继承
kotlin
// 使用组合而不是深层继承
interface Engine {
fun start()
fun stop()
}
interface Transmission {
fun shiftGear(gear: Int)
}
class PetrolEngine : Engine {
override fun start() = println("汽油引擎启动")
override fun stop() = println("汽油引擎停止")
}
class AutomaticTransmission : Transmission {
override fun shiftGear(gear: Int) = println("自动变速箱切换到档位 $gear")
}
// 使用组合
class ModernCar(
private val engine: Engine,
private val transmission: Transmission
) {
fun start() {
engine.start()
transmission.shiftGear(1)
}
fun stop() {
transmission.shiftGear(0)
engine.stop()
}
}3. 合理使用密封类
kotlin
// 用密封类表示有限的状态集合
sealed class ApiResponse<out T> {
object Loading : ApiResponse<Nothing>()
data class Success<T>(val data: T) : ApiResponse<T>()
data class Error(val code: Int, val message: String) : ApiResponse<Nothing>()
}
// 编译器确保when表达式的完整性
fun handleResponse(response: ApiResponse<String>): String {
return when (response) {
is ApiResponse.Loading -> "加载中..."
is ApiResponse.Success -> "数据:${response.data}"
is ApiResponse.Error -> "错误 ${response.code}: ${response.message}"
// 不需要else分支,编译器保证完整性
}
}下一步
掌握了继承和多态后,让我们学习Kotlin中的正则表达式处理。
下一章: 正则表达式
练习题
- 设计一个图形绘制系统,使用继承实现不同的图形类型
- 创建一个员工管理系统,展示多态性在薪资计算中的应用
- 实现一个游戏装备系统,使用抽象类和接口设计武器和防具
- 设计一个文件处理系统,使用密封类表示不同的处理结果
- 创建一个动物园管理系统,展示多重继承和接口实现的使用