Kotlin 面向对象
Kotlin 是一种面向对象的语言,完全支持面向对象编程(OOP)。本章将详细介绍类、对象、继承、接口等核心概念。
类定义
基本语法
// 定义类
class Person {
// 属性
var name: String = ""
var age: Int = 0
// 方法
fun sayHello() {
println("Hello, I am $name")
}
}
// 创建对象
fun main() {
val person = Person()
person.name = "Tom"
person.age = 25
person.sayHello()
}
构造函数
Kotlin 中的构造函数有主构造函数和次构造函数之分:
主构造函数
// 主构造函数 - 在类名后声明
class Person(val name: String, var age: Int) {
// 类体
}
fun main() {
val person = Person("Tom", 25)
println(person.name) // Tom
person.age = 26
}
构造函数参数属性化
class Person(
val name: String, // 自动生成 val name 属性
var age: Int, // 自动生成 var age 属性
val email: String = "" // 默认参数
)
fun main() {
val person = Person("Tom", 25)
println("${person.name}, ${person.age}")
}
init 初始化块
class Person(name: String, age: Int) {
val name: String
var age: Int
// 初始化块
init {
require(name.isNotEmpty()) { "Name cannot be empty" }
require(age >= 0) { "Age cannot be negative" }
this.name = name
this.age = age
println("Person created: $name, $age")
}
}
fun main() {
val person = Person("Tom", 25)
}
次构造函数
class Person(val name: String) {
var age: Int = 0
// 次构造函数
constructor(name: String, age: Int) : this(name) {
this.age = age
}
// 多个次构造函数
constructor(name: String, age: Int, email: String) : this(name, age) {
println("Email: $email")
}
}
fun main() {
val p1 = Person("Tom")
val p2 = Person("Tom", 25)
val p3 = Person("Tom", 25, "[email protected]")
}
属性
属性声明
class Person {
// 可变属性
var name: String = ""
// 只读属性
val id: String = ""
// 延迟初始化属性
lateinit var nickname: String
// 计算属性
val isAdult: Boolean
get() = age >= 18
var age: Int = 0
private set // 只能在类内部修改
// 自定义 getter/setter
var description: String = ""
get() = "Person: $name"
set(value) {
field = value.uppercase()
}
}
fun main() {
val person = Person()
person.name = "Tom"
person.age = 20
println(person.isAdult) // true
println(person.description)
}
延迟初始化
class Person {
lateinit var name: String // 延迟初始化
fun initialize() {
name = "Tom"
}
}
// 可空类型延迟初始化
class Person2 {
var name: String by Delegates.notNull<String>()
}
fun main() {
val person = Person()
// println(person.name) // 错误!未初始化
person.initialize()
println(person.name) // Tom
}
可见性修饰符
// 默认 public(可以省略)
class PublicClass
// 仅同类可见
private class PrivateClass
// 同模块可见
internal class InternalClass
// 跨模块可见
// open class BaseClass // 基类需要 open
public open class BaseClass
class Person {
// 默认 public
var name: String = ""
// 私有
private var secret: String = ""
// 内部(模块内)
internal var internalField: String = ""
// protected - 子类可见
protected var protectedField: String = ""
private fun privateMethod() {}
internal fun internalMethod() {}
protected fun protectedMethod() {}
}
继承
类继承基本语法
// 基类需要用 open 标记
open class Animal(val name: String) {
open fun makeSound() {
println("...")
}
fun eat() {
println("$name is eating")
}
}
// 继承
class Dog(name: String, val breed: String) : Animal(name) {
override fun makeSound() {
println("$name says: Woof!")
}
}
fun main() {
val dog = Dog("Buddy", "Labrador")
dog.makeSound() // Buddy says: Woof!
dog.eat() // Buddy is eating
}
调用父类
open class Shape {
open fun draw() {
println("Drawing shape")
}
fun describe() {
println("This is a shape")
}
}
class Circle(val radius: Double) : Shape() {
override fun draw() {
super.draw() // 调用父类方法
println("Drawing circle with radius $radius")
}
}
fun main() {
Circle(5.0).draw()
// 输出:
// Drawing shape
// Drawing circle with radius 5.0
}
多态
open class Shape {
open fun draw() = println("Drawing shape")
}
class Circle : Shape() {
override fun draw() = println("Drawing circle")
}
class Square : Shape() {
override fun draw() = println("Drawing square")
}
fun main() {
val shapes: List<Shape> = listOf(Circle(), Square(), Circle())
// 多态:调用相同方法,不同行为
shapes.forEach { it.draw() }
}
接口
接口定义
// 定义接口
interface Drawable {
// 抽象属性
val color: String
// 抽象方法
fun draw()
// 默认实现
fun describe() {
println("A drawable object with color $color")
}
}
class Circle(override val color: String, val radius: Double) : Drawable {
override fun draw() {
println("Drawing circle with radius $radius")
}
}
fun main() {
val circle = Circle("red", 5.0)
circle.draw()
circle.describe()
}
接口继承
interface A {
fun methodA()
}
interface B {
fun methodB()
}
// 继承多个接口
interface C : A, B {
fun methodC()
}
class Implementation : C {
override fun methodA() = println("A")
override fun methodB() = println("B")
override fun methodC() = println("C")
}
接口 vs 抽象类
| 特性 | 接口 | 抽象类 |
|---|---|---|
| 继承数 | 多继承 | 单继承 |
| 属性 | 抽象属性 | 可有具体属性 |
| 方法 | 可有默认实现 | 可有具体方法 |
| 构造函数 | 无 | 有 |
| 状态 | 无 | 可有成员变量 |
数据类
数据类自动生成 equals()、hashCode()、toString()、copy() 等方法:
// 定义数据类
data class User(val name: String, val age: Int, val email: String = "")
fun main() {
val user1 = User("Tom", 25, "[email protected]")
val user2 = User("Tom", 25, "[email protected]")
// 自动生成的 toString()
println(user1) // User(name=Tom, age=25, [email protected])
// 自动生成的 equals()
println(user1 == user2) // true
// 自动生成的 copy()
val user3 = user1.copy(name = "Jerry")
println(user3) // User(name=Jerry, age=25, [email protected])
// 解构声明
val (name, age, email) = user1
println("$name, $age, $email")
}
对象声明(单例)
// 对象声明 - 单例
object DatabaseConfig {
const val URL = "jdbc:mysql://localhost:3306/mydb"
const val MAX_CONNECTIONS = 10
fun connect() {
println("Connecting to $URL")
}
}
fun main() {
// 直接访问
DatabaseConfig.connect()
println(DatabaseConfig.MAX_CONNECTIONS)
}
伴生对象
class MyClass private constructor() {
// 伴生对象 - 相当于静态成员
companion object {
const val TAG = "MyClass"
fun create(): MyClass = MyClass()
// 类似于静态方法
fun factoryMethod() = MyClass()
}
}
fun main() {
val instance = MyClass.create()
println(MyClass.TAG)
}
密封类
密封类限制类的继承层次:
// 密封类 - 有限子类
sealed class Result {
class Success(val data: String) : Result()
class Error(val message: String) : Result()
object Loading : Result()
}
// when 必须 exhaustive
fun handleResult(result: Result) = when (result) {
is Result.Success -> println("Success: ${result.data}")
is Result.Error -> println("Error: ${result.message}")
is Result.Loading -> println("Loading...")
}
fun main() {
handleResult(Result.Success("Data"))
handleResult(Result.Error("Not found"))
handleResult(Result.Loading)
}
枚举类
// 枚举类
enum class Direction {
NORTH, SOUTH, EAST, WEST
}
// 带属性和方法的枚举
enum class Color(val rgb: Int) {
RED(0xFF0000),
GREEN(0x00FF00),
BLUE(0x0000FF);
fun hex() = "#${Integer.toHexString(rgb)}"
}
fun main() {
println(Direction.NORTH)
println(Color.RED.hex())
}
嵌套类和内部类
class Outer {
val outerValue = 10
// 嵌套类 - 相当于 Java 静态内部类
class Nested {
fun nestedMethod() = "Nested method"
}
// 内部类 - 持有外部类引用
inner class Inner {
fun innerMethod() = outerValue
}
}
fun main() {
// 访问嵌套类
println(Outer.Nested().nestedMethod())
// 访问内部类
println(Outer().Inner().innerMethod())
}
小结
本章我们学习了:
- 类定义:属性、方法、构造函数
- 主构造函数:参数属性化、init 块
- 次构造函数:多个构造函数
- 属性:var/val、getter/setter、计算属性
- 可见性修饰符:public/private/internal/protected
- 继承:override、super 调用、多态
- 接口:定义、实现、多继承
- 数据类:自动生成方法、解构
- 单例:object 声明
- 伴生对象:静态成员
- 密封类:受限继承
- 枚举类:常量集合
练习
- 创建一个 Person 类,包含姓名、年龄、邮箱属性
- 创建一个数据类 User,实现 copy 和解构
- 创建一个接口 Flyable,包含 fly() 方法,创建实现类 Bird
- 使用密封类实现 Result 类型(Success/Error/Loading)
- 创建一个单例 ConfigManager 类