object关键字:
使用object关键字,你可以定义一个只能产生一个实例的类-单例
使用object关键字有三种方式
对象声明-对象表达式-伴生对象
对象声明:
对象声明有利于组织代码和管理状态,尤其是管理整个应用运行生命周期内的某些一致性
状态。
object ApplicationConfig{
init {
println("ApplicationConfig loading...")
}
fun doSomething(){
println("dosomething")
}
}
fun main() {
//类名,实例名
ApplicationConfig.doSomething()
println(ApplicationConfig)
println(ApplicationConfig)
}
对象表达式:
有时候你不一定非要定义一个新的命名类不可,也许你需要某个现有类的一种变体实例,但只需用-次就行了,事实上,对于这种用完就丢的类实例,连命名都可以省了。这个对象表达式是XX的子类,这个匿名类依然遵循object关键字的一个规则,即一旦实例化,该匿名类只能有唯一一个实例存在。
open class Player{
open fun load()= "loading nothing."
}
fun main() {
val p=object : Player(){
override fun load() = "anonymous nothing.."
}
println(p.load())
}
伴生对象:
如果你想将某个对象的初始化和一个类实例捆绑在一起,可以考虑使用伴生对象,使用companion修饰符,你可以在一个类定义里声明一个伴生对象,一个类里只能有一个伴生对象。
open class ConfigMap{
companion object {
private const val PATH = "Xxxx"
fun load() = File(PATH).readBytes()
}
}
fun main() {
//static
ConfigMap.load()
}
嵌套类
如果一个类只对另一个类有用,那么将其嵌入到该类中并使这两个类保持在一起是合乎逻辑的,可以使用嵌套类
class Player2{
class Equipment(var name : String) {
fun show() = println("equipment:$name")
}
fun batter(){
}
}
fun main() {
Player2.Equipment ("sharp knife") .show()
}
数据类:
数据类,是专门设计用来存储数据的类
数据类提供了toString的个性化实现
==符号默认情况下,比较对象就是比较它们的引用值,数据类提供了equals和hashCode的个性化实现
data class Coordinate(var x: Int, var y: Int) {
val isInBounds = x > 0 && y > 0
}
fun main() {
println(Coordinate(10, 20))
//==比较内容,equals ,Any 默认实现===,比较引用
//===比较的是引用
println(Coordinate(10, 20) == Coordinate(10, 20))
}
copy:
除了重写Any类的部分函数,提供更好用的默认实现外,数据类还提供了一个函数,它可以用来方便地复制一个对象。假设你想创建一个Student实例,除了name属性它拥有和另一个现有Student实例完全一样的属性值,如果Student是个数据类,那么复制现有Student实例就很简单了,只要调用copy函数,给想修改的属性传入值参就可以了。
data class Student(var name: String, val age: Int) {
private val hobby = "music"
val subject: String
// var score = 0
init {
println("initializing student")
subject = "math"
}
constructor(_name: String) : this(_name, 10) {
// score = 10
}
override fun toString(): String {
return "Student(name='$name', age=$age, hobby='$hobby', subject='$subject', score=$score)"
}
}
fun main() {
val s = Student("Jack")
val copy: Student = s.copy(name = "Rose")
println(s)
println(copy)
}
解构声明:
解构声明的后台实现就是声明component1、component2等若干个组件函数,让每个函数负责管理你想返回的一个属性数据,如果你定义一个数据类,它会自动为所有定义在主构造函数的属性添加对应的组件函数
class PlayerScore(val experience: Int, val level: Int) {
operator fun component1() = experience
operator fun component2() = level
}
fun main() {
val (x, y) = PlayerScore(10, 20)
println("$x , $y")
}
运算符重载:
data class Coordinate(var x: Int, var y: Int) {
val isInBounds = x > 0 && y > 0
operator fun plus(other: Coordinate) = Coordinate( x + other.x, y + other.y)
}
fun main() {
val c1 = Coordinate(10, 20)
val c2 = Coordinate(10, 20)
println(c1 + c2)
}
枚举类:
枚举类,用来定义常量集合的一种特殊类
enum class Direction {
EAST,
WEST,
SOUTH,
NORTH
}
fun main() {
println(Direction.EAST)
println(Direction.EAST is Direction)
}
枚举类也可以定义函数
enum class Direction2(private val coordinate: Coordinate) {
EAST(Coordinate(1, 0)),
WEST(Coordinate(-1, 0)),
SOUTH(Coordinate(-1, 0)),
NORTH(Coordinate(1, 0));
fun updateCoordinate(playerCoordinate: Coordinate) =
Coordinate(
playerCoordinate.x + coordinate.x,
playerCoordinate.y + coordinate.y
)
}
fun main() {
println(Direction2.EAST.updateCoordinate(Coordinate(10,20)))
}