You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求举例解释Kotlin普通类与数据类方法默认实现的相关要点

Kotlin普通类与数据类核心差异详解

一、数据类解构声明(第二要点示例)

很多人实践时容易踩坑的点:数据类会自动生成componentN()方法支持解构声明,普通类必须手动实现才能用。

数据类的解构(自动支持)

data class User(val name: String, val age: Int)

fun main() {
    val user = User("Alice", 28)
    // 直接解构主构造函数的属性
    val (name, age) = user
    println("Name: $name, Age: $age") // 输出:Name: Alice, Age: 28
}

普通类的解构(需手动实现)

普通类默认没有componentN()方法,直接用解构会编译报错,必须手动声明:

class User(val name: String, val age: Int) {
    // 必须手动实现对应数量的component方法
    operator fun component1(): String = name
    operator fun component2(): Int = age
}

fun main() {
    val user = User("Bob", 30)
    val (name, age) = user
    println("Name: $name, Age: $age") // 输出:Name: Bob, Age: 30
}

二、自动生成方法的属性范围差异(第三要点详解)

数据类会仅使用主构造函数中声明的属性,为toString()、hashCode()、copy()、componentN()、equals()方法提供默认实现;而普通类中这些方法的实现可使用主构造函数中声明或未声明的属性。

数据类:仅主构造属性参与自动方法

数据类的自动实现方法只会认主构造里的属性,类内部额外定义的属性不会被包含:

data class User(val name: String, val age: Int) {
    // 非主构造的额外属性
    var email: String = ""
}

fun main() {
    val user1 = User("Alice", 28).apply { email = "alice@test.com" }
    val user2 = User("Alice", 28).apply { email = "alice_diff@test.com" }
    
    // equals只比较name和age,email不同仍返回true
    println(user1 == user2) // 输出:true
    
    // toString只显示主构造属性
    println(user1) // 输出:User(name=Alice, age=28)
    
    // copy仅复制主构造属性,email保留默认值
    val user3 = user1.copy()
    println(user3.email) // 输出:""
}

普通类:自由选择参与方法的属性

普通类默认继承自Any的方法(equals比较引用、toString输出类名+哈希),如果手动重写这些方法,可以自由决定包含哪些属性(主构造或类内部定义的都可以):

class User(val name: String, val age: Int) {
    var email: String = ""
    
    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false
        other as User
        // 手动包含name、age、email三个属性
        return name == other.name && age == other.age && email == other.email
    }
    
    override fun hashCode(): Int {
        var result = name.hashCode()
        result = 31 * result + age
        result = 31 * result + email.hashCode()
        return result
    }
    
    override fun toString(): String {
        return "User(name='$name', age=$age, email='$email')"
    }
}

fun main() {
    val user1 = User("Alice", 28).apply { email = "alice@test.com" }
    val user2 = User("Alice", 28).apply { email = "alice_diff@test.com" }
    
    // equals比较所有属性,email不同返回false
    println(user1 == user2) // 输出:false
    
    // toString显示所有属性
    println(user1) // 输出:User(name='Alice', age=28, email='alice@test.com')
}

内容的提问来源于stack exchange,提问作者eng.abeer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 10:06:14