Kotlin-特殊类型

article/2025/7/19 12:02:20

文章目录

  • 数据类型
  • 枚举类型
  • 匿名类和伴生对象
    • 单例类
    • 伴生对象

数据类型

声明一个数据类非常简单:

//在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(student1==student2)println(student1)val (name, age) = student1println("$name, $age")
}

在这里插入图片描述
为了确保生成代码的一致性和有效性,数据类必须满足以下要求:

  • 主构造函数中至少有一个参数
  • 主构造函数中的参数必须标记为valvar
  • 数据类不能是抽象的,可继承的,密封的或内部的

此外,数据类的成员属性生成遵循以下规则:

  • 如果数据类主体中,.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(student1==student2)println(student1)
}

在这里插入图片描述
数据类自带一个拷贝对象的函数,使用.copy()函数复制对象

data class Student(var name: String, var age: Int)fun main() {val student = Student("小明", 18)val copyStudent = student.copy()println(student==copyStudent)println(student===copyStudent)
}

在这里插入图片描述
还允许修改一些属性,而其余保持不变

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) //使用构造方法
}

伴生对象在类加载的时候就自动创建好了


http://www.hkcw.cn/article/CNepPIIuEW.shtml

相关文章

大疆上云API+流媒体服务器部署实现直播功能

根据官网文档上云API,先将官方提供的Demo部署起来,后端和前端服务环境搭建请参考官方文档。因为官方文档没有对直播这块的环境搭建进行说明,所以下面主要对直播功能环境搭建做一个记录,仅供参考,如有不足之处&#xff…

大模型-attention汇总解析之-GQA

从上面的图可以看出,MHA是一个attention 头有自己独立的kv cache 缓存,这样子的计算效果是最好的,同时kv cache 也是最完善的,意味着也是最占用内存的。MQA 进行了极致的kv cache 共享,那么能不能对多头进行分组&#…

Haption在危险、挑战性或受限环境中操作的情况提供了一种创新的遥操作解决方案

Haption Virtuose 6D TAO是一款拥有7个主动自由度的触觉设备,专为虚拟现实环境交互而设计。 它与Virtuose的一系列软件解决方案兼容,可让您直接在CAD软件中使用该设备进行装配仿真,并在3D游戏引擎中使用该设备,从而打造更加逼真的…

[STM32问题解决(2)]STM32通过串口与PC通信,打开串口助手后无法在打开状态下下载程序和复位STM32

问题回顾 最近学习STM32单片机,经常使用STM32通过USART1串口与PC的串口助手进行通信。为了简单便捷,通常在打开串口的状态下下载程序。这样子下载程序后,STM32发出的信号,PC马上可以收到。 但是,突然出现了一个问题&a…

JVM内存模型(运行时数据区)

目录 编者想说 1、内存模型图 2、栈 3、程序计数器 3、堆 4、方法区(元空间) 5、本地方法栈(Native Method Stack) 编者想说 通过上一篇文章的对JVM的体系结构以及它的演化,我们对JVM有了一个比较清晰的认识&…

突破铁芯CT局限:罗氏线圈的“无磁饱和”技术深度解读

罗氏线圈互感器:关键应用场景解析 罗氏线圈(Rogowski Coil)互感器以其独特的性能优势,成为测量交流电流(尤其适用于变化快、幅度大或频率范围广的电流)的理想选择。其核心优势在于宽频带、无磁饱和、尺寸灵…

Oracle数据仓库在医院的应用场景

2025年3月28日,我作为会议组织者,在宁波组织了数据仓库在医院的应用场景,会议主要议题如下: 1、解析医院多源异构数据(HIS/LIS/EMR/PACS)实时整合的技术方案 2、Oracle exadata在构建全院级数据仓库的性能优…

JavaScript引用类型

引用类型概述 变量值的两种存储方式 1原始值 2引用值 基本数据类型 5种基本数据类型都是按照原始值的方式来存储的,也叫原始数据类型。 undefined表示没有存储值,也是一种基本数据类型;null表示存储了值,但是空指针&#xff…

实战项目7(10)【待更新......】

任务场景一 按照下图完成网络拓扑搭建和配置 任务要求: 按照以上网络拓扑,将直连路由重发布至OSPF动态路由信息中,实现终端PC间可以正常访问。 【R1】配置 【R2】配置 【R3】配置 任务场景二 按照下图完成网络拓扑搭建和配置 任务要求&…

C# 将HTML文档、HTML字符串转换为图片

在.NET开发中,将HTML内容转换为图片的需求广泛存在于报告生成、邮件内容存档、网页快照等场景。Free Spire.Doc for .NET作为一款免费的专业文档处理库,无需Microsoft Word依赖,即可轻松实现这一功能。本文将深入解析HTML文档和字符串转图片两…

MySql(八)

目录 查询 1)准备一张表 2)准备数据 3)查询表中的数据 4)只查表中的某些列 5)为列起别名 使用 as 不使用as 查询 1)准备一张表 CREATE table role( roleid INT PRIMARY KEY AUTO_INCREMENT, rolename VA…

Redis Sorted Set 深度解析:从原理到实战应用

Redis Sorted Set 深度解析:从原理到实战应用 在 Redis 丰富的数据结构家族中,Sorted Set(有序集合)凭借独特的设计和强大的功能,成为处理有序数据场景的得力工具。无论是构建实时排行榜,还是实现基于时间的…

95套HTML高端大数据可视化大屏源码分享

概述​​ 在大数据时代,数据可视化已成为各行各业的重要需求。这里精心整理了95套高端HTML大数据可视化大屏源码,这些资源采用现代化设计风格,可帮助开发者快速构建专业的数据展示界面。 ​​主要内容​​ ​​1. 设计风格与特点​​ 采用…

Python 中的空间 KDE 图

数据:布里斯班致命车祸 我将使用昆士兰道路车辆事故数据集,该数据集可从昆士兰开放数据门户获取。该数据集提供了昆士兰州2001年1月1日至2023年11月30日期间所有已报告的道路交通事故的地点和特征信息。 我只想关注致命事故,所以唯一需要关…

变焦位移计:机器视觉如何克服人工疲劳与主观影响?精准对结构安全实时监测

变焦视觉位移监测与人工监测的对比 人工监测是依靠目测检查或借助于全站仪,水准仪,RTK等便携式仪器测量得到的信息,但是随着整个行业的发展,传统的人工监测方法已经不能满足监测需求,从人工监测到自动化监测已是必然趋…

【JavaWeb】Maven、Servlet、cookie/session

目录 5. Maven6. Servlet6.1 Servlet 简介6.2 HelloServlet6.3 Servlet原理6.4 Mapping( **<font style"color:rgb(44, 44, 54);">映射 ** )问题6.5 ServletContext6.6 HttpServletResponse<font style"color:rgb(232, 62, 140);background-color:rgb(…

【Day40】

DAY 40 训练和测试的规范写法 知识点回顾&#xff1a; 彩色和灰度图片测试和训练的规范写法&#xff1a;封装在函数中展平操作&#xff1a;除第一个维度batchsize外全部展平dropout操作&#xff1a;训练阶段随机丢弃神经元&#xff0c;测试阶段eval模式关闭dropout 作业&#x…

GEARS以及与基础模型结合

理解基因扰动的反应是众多生物医学应用的核心。然而&#xff0c;可能的多基因扰动组合数量呈指数级增长&#xff0c;严重限制了实验探究的范围。在此&#xff0c;图增强基因激活与抑制模拟器&#xff08;GEARS&#xff09;&#xff0c;将深度学习与基因-基因关系知识图谱相结合…

【C++】入门基础知识(1.5w字详解)

本篇博客给大家带来的是一些C基础知识&#xff01; &#x1f41f;&#x1f41f;文章专栏&#xff1a;C &#x1f680;&#x1f680;若有问题评论区下讨论&#xff0c;我会及时回答 ❤❤欢迎大家点赞、收藏、分享&#xff01; 今日思想&#xff1a;微事不通&#xff0c;粗事不能…

[SWPUCTF 2023 秋季新生赛]Classical Cipher203分古典密码Base家族栅栏密码

下载附件解压得到txt文件 得到信息 U2FsdGVkX19aQNEomnRqmmLlI9qJkzr0pFMeMBF99ZDKTF3CojpkTzHxLcu/ZNCYeeAV3/NEoHhpP5QUCK5AcHJlZBMGdKDYwko5sAATQ 用在线网站进行解密 解密得到 TGhmYlMlXXNwX2BTb3NoQWcye1VweSRfcXEGdmBheDx0I1BkMXdfXG0ldzdbGBy 栅栏密码用在线网站进行…