嵌套类

如果一个类只对另一个类有用,那么将其嵌入到该类并使这两个类保持在一起是合乎逻辑的,可以使用前套类

class Player2 {

class Equipment(var name: String) {
fun show() = println("equipment: $name")
}

fun battle() {
}
}

fun main() {
Player2.Equipment("knife").show()
}

数据类

  • 数据类,是专门用来存储数据的类

  • 数据类提供了toString的个性化实现

  • ==符号默认情况下,比较对象就是比较它们的引用值,数据类提供了equalshashCode的个性化实现

data class Coordinate(var x: Float, var y: Float) {
var isInBounds = x > 0 && y > 0
}

fun main() {
println(Coordinate(119.2f,20.1f))
println(Coordinate(119.2f,20.1f) == Coordinate(119.2f,20.1f)) //true
}

为什么上面的 ==符号会是true,如果用data修饰的话,会默认重写equals,而我们知道==比较的是内容,也就是equals,===比较的是引用,重写equals的方法如下

public boolean equals(@Nullable Object var1) {
if (this != var1) {
if (var1 instanceof Coordinate) {
Coordinate var2 = (Coordinate)var1;
if (Float.compare(this.x, var2.x) == 0 && Float.compare(this.y, var2.y) == 0) {
return true;
}
}

return false;
} else {
return true;
}
}

可以看到,比较了类的每一个属性是否相等

扩展

如果我们在Coordinate类上加上另一个自定的类作为属性

data class Coordinate(var x: Float, var y: Float,val user: User) {
var isInBounds = x > 0 && y > 0
}
class User(val name:String,val age: Int)

现在我们来判断,以下是否相等

println(Coordinate(119.2f,20.1f,User("Lee",20)) == Coordinate(119.2f,20.1f,User("Lee",20))) 

答案是false,因为会去比较两个user对象,是否相等

Intrinsics.areEqual(this.user, var2.user)

如果把User类改为数据类,那么结果就会是true.

Copy

除了重写Any类的部分函数,提供更好的默认实现外,数据类还提供了一个函数,它可以用来方便地复制一个对象

package s3

data class Student(var name: String,val age: Int) {
private val hobby = "music"
val subject: String
var score: Int = 0


init {
subject = "math"
}
constructor(_name: String): this(_name,10) {
score = 90 //TODO
}

override fun toString(): String {
return "Student(name='$name', age=$age, hobby='$hobby', subject='$subject', score=$score)"
}
}

fun main() {
val jack = Student("Jack")
val rose = jack.copy(name = "Rose")
//rose.score = 90 //需要手动赋值
println(jack)//Student(name='Jack', age=10, hobby='music', subject='math', score=90)
println(rose)//Student(name='Rose', age=10, hobby='music', subject='math', score=0)
}

这里需要注意的是,copy的时候会重新new一个对象,次构造函数里面的赋值操作并不会进行,所以需要手动赋值