Kotlin 从入门到进阶 之面向对象 OOP 模块(三)

Kotlin 面向对象 OOP 模块

1. 类与构造器

主构造器

kotlin 复制代码
// 主构造器:类头声明
class User(var name: String, val age: Int)

// 主构造器 + 属性声明
class Person(
    var name: String,           // var:可变属性
    val age: Int,               // val:只读属性
    var email: String = "unknown"  // 默认值
)

// 主构造器参数初始化方式一:直接在属性声明中赋值
class Config(val debug: Boolean = false, var timeout: Int = 3000)

// 主构造器参数初始化方式二:init 块
class Student(name: String, score: Int) {
    val studentName: String
    val studentScore: Int

    init {
        require(score in 0..100) { "Score must be 0-100" }
        studentName = name.uppercase()
        studentScore = score
    }
}

次构造器

kotlin 复制代码
class Person {
    var name: String
    var age: Int

    // 次构造器必须委托主构造器
    constructor(name: String) : this(name, 0)

    // 继续委托
    constructor(name: String, age: Int) {
        this.name = name
        this.age = age
    }
}

// 次构造器重载示例
class Router {
    var ip: String
    var port: Int

    constructor(ip: String) : this(ip, 80)

    constructor(ip: String, port: Int) {
        this.ip = ip
        this.port = port
    }
}

init 初始化块

kotlin 复制代码
class Circle(val radius: Double) {
    val area: Double

    init {
        require(radius > 0) { "Radius must be positive" }
        area = Math.PI * radius * radius
    }
}

// 多个 init 按顺序执行
class Example(value: Int) {
    val prop1: String

    init {
        prop1 = "Step 1: $value"
    }

    init {
        prop1 += " -> Step 2"
    }
}

2. 成员属性与延迟初始化

kotlin 复制代码
// 标准属性
class Person {
    var name: String = ""
    val age: Int = 0
}

// lateinit:延迟初始化(var,只能用于可空类型)
class NetworkManager {
    lateinit var client: OkHttpClient

    fun initialize() {
        client = OkHttpClient.Builder().build()
    }

    fun request() {
        if (::client.isInitialized) {
            // 安全访问
        }
    }
}

// by lazy:惰性初始化(val,线程安全)
class Repository {
    val database: AppDatabase by lazy {
        Room.databaseBuilder(
            applicationContext,
            AppDatabase::class.java,
            "app_db"
        ).build()
    }
}

// 内联属性(inline property,无 backing field)
class TokenManager {
    inline var token: String?
        get() = getSharedPreferences().getString("token", null)
        set(value) = getSharedPreferences().edit().putString("token", value).apply()
}

3. 封装与继承、重写

kotlin 复制代码
// 封装:默认 public(final),需要继承时用 open
open class Animal {
    open fun sound() = "..."

    fun move() = "moving"
}

// 继承
class Dog : Animal() {
    override fun sound() = "Woof!"
}

// 方法重写
open class BaseActivity {
    open fun onCreate() {}

    fun helper() {}   // 不可重写
}

class MainActivity : BaseActivity() {
    override fun onCreate() {
        super.onCreate()
    }
}

// 属性重写
open class View {
    open var width: Int = 0
    open val height: Int = 0
}

class Button : View() {
    override var width: Int = 100
    override val height: Int = 50
}

// 禁止重写:final(Kotlin 默认类即为 final)
// class FinalClass { }  // 不可被继承

4. 抽象类与接口

kotlin 复制代码
// 抽象类:可包含抽象属性和抽象方法
abstract class Shape {
    abstract fun area(): Double

    open fun describe() = "Shape"
}

// 接口:Kotlin 1.9+ 支持具体方法(default 方法)
interface Drawable {
    val color: String

    fun draw() {
        println("Drawing with color: $color")
    }

    fun outline()  // 抽象方法
}

// 实现接口和抽象类
class Circle(private val radius: Double) : Shape(), Drawable {
    override val color: String = "Red"

    override fun area(): Double = Math.PI * radius * radius

    override fun draw() {
        println("Circle area: ${area()}")
    }

    override fun outline() {
        println("Circle outline")
    }
}

// 多接口实现(冲突时需手动解决)
interface A {
    fun method() = "A"
}

interface B {
    fun method() = "B"
}

class C : A, B {
    override fun method(): String {
        return "${A.super.method()} + ${B.super.method()}"
    }
}

5. 数据类 data class(实体类必备)

kotlin 复制代码
// 数据类:自动生成 equals / hashCode / toString / copy / componentN
data class User(
    val id: Long,
    var name: String,
    val email: String
)

// 自动生成方法使用示例
val user1 = User(1, "windCloud", "wind@example.com")
val user2 = user1.copy(name = "OtherName")  // copy:浅拷贝,可修改属性

println(user1)          // User(id=1, name=windCloud, email=wind@example.com)
println(user1 == user2)  // false

// 解构
val (id, name, email) = user1
// id=1, name=windCloud, email=wind@example.com

// equals / hashCode 自动生成
val user3 = User(1, "windCloud", "wind@example.com")
println(user1 == user3)  // true(内容相同)

// hashCode 自动生成(基于 id 和 name)
val hash1 = user1.hashCode()
val hash2 = user3.hashCode()
println(hash1 == hash2)  // true

// 数据类用于 Room / Retrofit
@Entity
data class Article(
    @PrimaryKey val id: Long,
    val title: String,
    val content: String,
    val timestamp: Long = System.currentTimeMillis()
)

// 注意:数据类限制
// - 必须至少有一个参数
// - 参数默认 val/var(自动生成对应属性)
// - 不能是 abstract、open、sealed、inner
// - 不能自定义 componentN()、copy()

6. 单例 object 与伴生对象 companion object

kotlin 复制代码
// 单例:object(线程安全,懒加载)
object DatabaseManager {
    private var db: AppDatabase? = null

    fun getInstance(): AppDatabase {
        if (db == null) {
            db = createDatabase()
        }
        return db!!
    }

    fun query(sql: String) {
        println("Executing: $sql")
    }
}

// 调用方式
DatabaseManager.query("SELECT * FROM users")

// 伴生对象:类似 Java static,属于类的静态成员
class HttpClient {
    val url: String

    companion object {
        private const val DEFAULT_BASE_URL = "https://api.example.com"

        // 静态方法
        fun create(): HttpClient {
            return HttpClient(DEFAULT_BASE_URL)
        }

        fun create(baseUrl: String): HttpClient {
            return HttpClient(baseUrl)
        }
    }

    constructor(url: String) {
        this.url = url
    }
}

// 调用
val client = HttpClient.create()

// 扩展伴生对象
fun HttpClient.Companion.withTimeout(timeout: Int): HttpClient {
    return HttpClient("").also { /* 配置 */ }
}

// 接口实现 + 伴生对象
interface Factory {
    fun create(): Any
}

class Product private constructor(val name: String) {
    companion object : Factory {
        override fun create(): Product = Product("Default")
        fun create(name: String) = Product(name)
    }
}

7. 枚举类 enum class

kotlin 复制代码
// 基础枚举
enum class Color {
    RED, GREEN, BLUE
}

// 带属性枚举
enum class HttpStatus(val code: Int) {
    OK(200),
    NOT_FOUND(404),
    SERVER_ERROR(500);

    fun description() = "HTTP $code"
}

// 实现接口的枚举
enum class Priority : Comparable<Priority> {
    LOW {
        override fun label() = "🔵 Low"
    },
    MEDIUM {
        override fun label() = "🟡 Medium"
    },
    HIGH {
        override fun label() = "🔴 High"
    };

    abstract fun label(): String
}

// 枚举遍历
Color.entries.forEach { println(it) }

// when 与枚举(编译器检查完备性)
fun handleStatus(status: HttpStatus): String {
    return when (status) {
        HttpStatus.OK -> "Success"
        HttpStatus.NOT_FOUND -> "Not found"
        HttpStatus.SERVER_ERROR -> "Server error"
        // 无需 else,因为编译器确保覆盖所有情况
    }
}

8. 密封类 sealed class(状态管理必备)

kotlin 复制代码
// 密封类:有限子类型,when 必须覆盖所有分支
sealed class Result<out T> {
    data class Success<T>(val data: T) : Result<T>()
    data class Error(val message: String) : Result<Nothing>()
    object Loading : Result<Nothing>()
    // 编译器确保 when 覆盖所有情况
}

// when 必须完备
fun handleResult(result: Result<*>) {
    val info = when (result) {
        is Result.Success -> "Data: ${result.data}"
        is Result.Error -> "Error: ${result.message}"
        Result.Loading -> "Loading..."
        // 无需 else
    }
}

// sealed class 嵌套 data class(状态机模式)
sealed class UiState<out T> {
    object Idle : UiState<Nothing>()
    object Loading : UiState<Nothing>()
    data class Success<T>(val value: T) : UiState<T>()
    data class Failure(val error: Throwable) : UiState<Nothing>()
}

// ViewModel 使用示例
class MyViewModel : ViewModel() {
    private val _state = MutableStateFlow<UiState<List<String>>>(UiState.Idle)

    fun load() {
        viewModelScope.launch {
            _state.value = UiState.Loading
            try {
                val data = repository.fetchData()
                _state.value = UiState.Success(data)
            } catch (e: Exception) {
                _state.value = UiState.Failure(e)
            }
        }
    }
}

9. 嵌套类、内部类、匿名内部类

嵌套类(不持有外部类引用)

kotlin 复制代码
// 嵌套类:不带 inner 修饰符,不持有外部类引用
class Outer {
    private val outerValue = 10

    class Nested {
        // fun access() = outerValue  // 编译错误,无法访问外部类成员
        fun hello() = "Hello from Nested"
    }
}

// 调用
val nested = Outer.Nested()

内部类(持有外部类引用)

kotlin 复制代码
// 内部类:带 inner 修饰符,可访问外部类成员
class Outer {
    private val outerValue = 10

    inner class Inner {
        val value = outerValue   // OK,可访问外部类成员
        fun access() = outerValue * 2
    }
}

val inner = Outer().Inner()
inner.access()  // 20

匿名内部类(object expression)

kotlin 复制代码
// 匿名内部类:object: 接口/抽象类
val clickListener = object : View.OnClickListener {
    override fun onClick(v: View?) {
        println("Clicked!")
    }
}

button.setOnClickListener(clickListener)

// 单方法接口可简化为 lambda(Kotlin 语法糖)
button.setOnClickListener { view ->
    println("Clicked via lambda!")
}

// 多方法接口(必须用 object)
val gestureListener = object : GestureDetector.OnGestureListener {
    override fun onDown(e: MotionEvent) = true
    override fun onShowPress(e: MotionEvent) {}
    override fun onSingleTapUp(e: MotionEvent) = true
    override fun onScroll(...) = false
    override fun onLongPress(e: MotionEvent) {}
    override fun onFling(...) = false
}

// 带接口 super type 的匿名类
abstract class AbstractClass {
    abstract fun doSomething()
}

val instance = object : AbstractClass() {
    override fun doSomething() {
        println("Doing something")
    }
}

快速对照表

概念 语法 关键特性
主构造器 class User(val name: String) 类头声明
次构造器 constructor(name: String) : this() 必须委托主构造器
init 块 init { ... } 初始化逻辑,多个按序执行
lateinit lateinit var name: String var,运行时初始化
by lazy val db by lazy { ... } val,线程安全惰性加载
open/override open class / override fun 控制继承与方法重写
abstract abstract class Shape 抽象类,不可实例化
interface interface Drawable { } 多实现,Kotlin 1.9+ 支持具体方法
data class data class User(val id: Long) 自动生成 equals/hashCode/toString/copy
object object Manager { } 单例,线程安全
companion object companion object { } 类静态成员,类似 Java static
enum class enum class Color { RED, GREEN } 有限实例,可带属性和行为
sealed class sealed class Result { } 有限子类型,when 完备性保证
嵌套类 class Outer.Nested 不持有外部类引用
内部类 inner class Inner 持有外部类引用
匿名内部类 object : Interface { } 接口/抽象类实现,无需显式命名
相关推荐
故事和你911 小时前
洛谷-数据结构2-1-二叉堆与树状数组2
开发语言·javascript·数据结构·算法·ecmascript·动态规划·图论
西西弟1 小时前
网络编程基础之TCP多线程并发服务器
服务器·网络·网络协议·tcp/ip
凯瑟琳.奥古斯特1 小时前
懒加载技巧优化栈增减操作(力扣3629)
开发语言·数据结构·算法
lihongli0001 小时前
关于c++中锁的种类与使用
java·开发语言·c++
hans汉斯1 小时前
基于LSTM与扩展卡尔曼滤波的无人机机载电子磁干扰补偿研究
开发语言·人工智能·算法·目标检测·lstm·人机交互·无人机
凯勒姆1 小时前
华为设备软考网工模板
服务器·网络·华为
赏金术士1 小时前
Kotlin 从入门到进阶 之Lambda & 集合高阶模块(四)
开发语言·windows·kotlin
yingjie1101 小时前
用mcc编译的MATLAB EXE被反编译了?这个工具能帮你加固
开发语言·matlab
Evand J1 小时前
【MATLAB绘图】三维曲面与二维映射组合图绘制,进阶教程与代码示例
开发语言·matlab·绘图