请求举例解释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
相关产品推荐
相关产品推荐

