国内优秀的设计网站,公司网站建设进度计划书,景区网站模板,青岛网站建设微信群文章目录 数据类型枚举类型匿名类和伴生对象单例类伴生对象 数据类型
声明一个数据类非常简单:
//在class前面添加data关键字表示为一个数据类
data class Student(var name: String, var age: Int)数据类声明后,编译器会根据主构造函数中声明的所有属性自动为其生成以下函数… 文章目录 数据类型枚举类型匿名类和伴生对象单例类伴生对象 数据类型
声明一个数据类非常简单:
//在class前面添加data关键字表示为一个数据类
data class Student(var name: String, var age: Int)数据类声明后,编译器会根据主构造函数中声明的所有属性自动为其生成以下函数:
.equals() / .hashCode().toString().componentN() 按声明顺序自动生成用于解构的函数.copy()用于对对象进行拷贝
举个栗子:
data class Student(var name: String, var age: Int)fun main() {val student1 Student(小明, 18)val student2 Student(小明, 18)println(student1student2)println(student1)val (name, age) student1println($name, $age)
}为了确保生成代码的一致性和有效性,数据类必须满足以下要求:
主构造函数中至少有一个参数主构造函数中的参数必须标记为val或var数据类不能是抽象的,可继承的,密封的或内部的
此外,数据类的成员属性生成遵循以下规则:
如果数据类主体中,.equals() .hashCode() 或 .toString()等函数存在显式(手动)实现,或者在父类中有final实现,则不会自动生成这些函数
data class Student(var name: String, var age: Int) {override fun toString(): String 我是自定义的toString
}fun main() {val student Student(小明, 18)println(student)
}如果父类具有open operator fun componentN()函数并返回兼容类型,数据类会生成相应的函数,并覆盖父类的函数,如果由于关键字导致无法重写父类对应的函数会直接导致报错 open class Person {//此函数必须是open的,否则无法被数据类继承open operator fun component1() 我想当太空人
}//自动覆盖父类的component1函数
data class Student(var name: String, var age: Int): Person() fun main() {val (name, age) Student(小明, 18)println($name, $age)
}不允许为.componentN()和.copy()函数提供显式实现 注意,编译器只会根据主构造函数中定义的属性生成对应函数,如果我们不希望某些属性被添加到自动生成的函数中,我们需要手动将其移出主构造函数:
data class Student(var name: String) {var age: Int 0 //age属性不会被处理
}fun main() {val student1 Student(小明)val student2 Student(小明)student1.age 17student2.age 18println(student1student2)println(student1)
}数据类自带一个拷贝对象的函数,使用.copy()函数复制对象
data class Student(var name: String, var age: Int)fun main() {val student Student(小明, 18)val copyStudent student.copy()println(studentcopyStudent)println(studentcopyStudent)
}还允许修改一些属性,而其余保持不变
data class Student(var name: String, var age: Int)fun main() {val student Student(小明, 18)val copyStudent student.copy(age 17)println(copyStudent)
}枚举类型
如果我们想要存储和表示自定义的多种状态,可以使用枚举类型
//在类前面添加enum表示枚举类
enum class TrafficLight {RED, YELLOW, GREEN
}fun main() {val light: TrafficLight TrafficLight.REDprintln(light)println(light.name) //name属性是String类型println(light.ordinal)println(TrafficLight.RED.ordinal)println(TrafficLight.YELLOW.ordinal)println(TrafficLight.GREEN.ordinal)
}枚举也可以具有成员,但不能命名为name,因为name用来返回枚举名称了
enum class TrafficLight(var type: String) {//枚举在定义时必须填写参数,如果后面还要编写函数之类的其他内容,需在末尾添加;RED(红灯), YELLOW(黄灯), GREEN(绿灯);fun isGreen() this GREENfun test() println(我是$type)
}fun main() {val light: TrafficLight TrafficLight.REDprintln(light.type)println(light.isGreen())light.test()
}枚举类型可以用于 when 表达式进行判断,因为它的状态是有限的
enum class TrafficLight(var type: String) {//枚举在定义时必须填写参数,如果后面还要编写函数之类的其他内容,需在末尾添加;RED(红灯), YELLOW(黄灯), GREEN(绿灯);
}fun main() {val light: TrafficLight TrafficLight.REDval result: String when (light) {TrafficLight.RED - 禁止通行TrafficLight.YELLOW - 减速通行/准备停下TrafficLight.GREEN - 正常通行}println(result)
}在枚举类中也可以编写抽象函数,但需要枚举自行实现
enum class TrafficLight(var type: String) {RED(红灯) {override fun test() println(我是红灯, 禁止通行)}, YELLOW(黄灯) {override fun test() println(我是黄灯, 是让你减速, 不是踩油门冲过去)}, GREEN(绿灯) {override fun test() println(我是绿灯, 速速离去)};abstract fun test()
}fun main() {val light: TrafficLight TrafficLight.REDlight.test()
}如果枚举实现了某个接口,既可以成员实现也可以统一实现
interface Message {fun test()
}enum class TrafficLight(var type: String): Message {RED(红灯) {override fun test() println(我是红灯, 禁止通行)}, YELLOW(黄灯) {override fun test() println(我是黄灯, 是让你减速, 不是踩油门冲过去)}, GREEN(绿灯) {override fun test() println(我是绿灯, 速速离去)};
}enum class TrafficLight(var type: String): Message {RED(红灯), YELLOW(黄灯), GREEN(绿灯);override fun test() println(回家收衣服咯)
}匿名类和伴生对象
fun main() {val obj object { //使用object关键字声明一个匿名类并创建对象val name 张三override fun toString() 我是匿名类, name: $name}println(obj)
}匿名类虽然没名字,也可以定义成员,不过不能定义任何构造函数
匿名类也可以作为某个类的子类定义,或是某个接口的实现
interface Person {fun chat()
}fun main() {val obj: Person object: Person {override fun chat() println(以心为鞘,以养利剑)}obj.chat()
}open class Human(val name: String)fun main() {val obj: Human object: Human(萧炎) {override fun toString() 我是$name}println(obj)
}单例类
object关键字除了用于声明匿名类型,也可以用于声明单例类(整个程序中只能存在一个对象)
object Singleton {private val name 超人强override fun toString(): String 我叫$name
}fun main() {val singleton Singleton //不能通过构造函数创建对象,通过类名直接得到此单例类的对象println(singleton)
}object Singleton {fun test() println(原神,启动!)
}fun main() {Singleton.test() //单例定义的函数使用类名直接就能调用
}伴生对象
实际上就是将一个单例类写到某个类内部
class Student(val name: String, val age: Int) {//使用companion关键字在内部编写一个伴生对象,它同样是单例的companion object Tools {//伴生对象定义的函数可以直接通过外部类名调用fun create(name: String, age: Int) Student(name, age)}
}fun main() {Student.create(小明, 18)Student(小红, 19) //使用构造方法
}伴生对象在类加载的时候就自动创建好了