Kotlin快速入门系列9

Kotlin对象表达式和对象声明

对象表达式

有时,我们想要创建一个对当前类有些许修改的对象同时又不想重新声明一个子类。如果是Java,可以用匿名内部类的概念来解决这个问题。kotlin的对象表达式和对象声明就是为了实现这一点(创建一个对某个类做了轻微改动的类的对象,且不需要去声明一个新的子类)。

对象表达式的格式:

Object[: 若干个父类型,中间用逗号分隔]

例如下例常见的,通过对象表达式实现的将一个匿名内部类的对象用于方法的参数中:

computer.addMouseListener(object : MouseAdapter() {override fun mouseClicked(e: MouseEvent) {// ...}override fun mouseRolled(e: MouseEvent) {// ...}
})

通过对象表达式可以越过类的定义直接得到一个对象:

fun main(args: Array<String>) {val site = object {var tips: String = "谷歌大法好"var url: String = "www.Google.com"}println(site.tips)println(site.url)
}

对应的控制台输出为:

如果超类有构造器,则需要传入合适的参数。多个超类在冒号之后使用逗号分隔,大抵格式如下:

open class BaseA(x: Int){public open val num: Int = x
}interface InterfaceB {...}val ab: A = object : BaseA(1) , InterfaceB{override val num = 15
}

用作类型的匿名对象,只能在局部和私有声明中。如果使用匿名对象作为public函数的返回值,或public属性的类型,则函数或属性的实际类型实际为匿名类的超类或Any(未声明任何超类)。匿名对象添加的成员不能被访问。下面是一个官网的例子:

class Demo{// 私有函数,所以返回类型为匿名对象类型private fun foo() = object {val x: String = "foo"}// Public函数,返回类型为Anyfun publicFoo() = object {val x: String = "FOO"}fun bar() {val x1: String = foo().x  // 有效val x2: String = publicFoo().x // 提示错误:无法引用x}
}

对象声明

在Kotlin中,使用 object 关键字来声明一个(单例)对象。这点跟Java是完全不一样的,在Java中,必须先有类,然后才能new出该类的对象并生成实例,也就是声明类和创建对象是两个分开的步骤,并有先后次序。在Kotlin中,我们可以使用object关键字在声明定义一个类的同时创建出一个对象,这就是所谓的对象声明

使用方法极其简单,在 object 关键字后跟⼀个名称即可,这样就直接声明了一个单例对象。

object DataProviderManager {fun registerDataProvider(provider: DataProvider) {
// ……}val allDataProviders: Collection<DataProvider>get() = // ……
}

要引⽤该对象,直接使⽤其名称即可:

DataProviderManager.registerDataProvider(……)

注意这里是单例,当你定义两个不同的变量来获取这个对象时,你会发现你并不能得到两个不同的变量,如下例我们只对一个对象实例进行了属性更改,但打印两个对象实例都会得到更改的属性:

object WebSite {var url:String = ""val web: String = "谷歌大法好"
}
fun main(args: Array<String>) {var s1 = WebSitevar s2 = WebSites1.url = "www.Google.com"println(s1.url)println(s2.url)
}

对应的控制台输出为:

与对象表达式不同的是,当对象声明在另一个类的内部时,这个对象并不能通过外部类的实例访问到该对象,而只能通过类名来访问,同样该对象也不能直接访问到外部类的方法和变量。

object WebSite {var web = "谷歌大法好"object DeskTop{var url = "www.Google.com"fun showName(){print{"desk legs $web"} // 错误,不能访问到外部类的方法和变量,打印结果为:Function0<java.lang.String>}}
}
fun main(args: Array<String>) {var site = WebSitesite.DeskTop.url // 提示错误,不能通过外部类的实例访问到该对象WebSite.DeskTop.url // 调用方式正确
}

伴生对象 

跟Java不同,在kotlin中,类是没有static方法的。多数情况下,Kotlin推荐的做法是使用包级别的函数作为静态方法。这里就引申除了另外一个关键字,companion。

在类内部的对象声明可以用 companion 关键字标记,这样它就与外部类关联在一起,我们可以直接通过外部类访问到对象的内部元素。

class DemoClass {companion object Factory {fun create(): DemoClass = DemoClass()}
}val instance = DemoClass.create()   // 变量可直接访问到对象的内部元素

我们可以直接省略掉该对象的对象名,然后使用 companion 替代需要声明的对象名:

class DemoClass {companion object {}
}val instance = DemoClass.Companion

这里需要注意的是,一个类里面只能声明一个内部关联对象,即关键字 companion 只能使用一次。

伴生对象的成员看起来像其他语言的静态成员,但在运行时他们仍然是真实对象的实例成员。在 JVM 平台,如果使⽤ @JvmStatic 注解,你可以将伴⽣对象的成员⽣成为真正的静态⽅法和字段。

差异性

最后总结下,对象表达式和对象声明之间有一个重要的语义差别:

· 对象表达式是在使用他们的地方立即执行的;

· 对象声明是在第一次被访问到时延迟初始化的;

· 伴生对象的初始化是在相应的类被加载(解析)时,与 Java 静态初始化器的语义相匹配。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/657508.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Mysql实现Postgresql中窗口函数row_number的功能

1. 描述 需要根据用户id&#xff0c;查询每个人得分第二高的科目信息 2. 表结构及数据 2.1 表结构 CREATE TABLE t_score (id bigint(20) NOT NULL AUTO_INCREMENT,user_id bigint(20) NOT NULL,score double NOT NULL,subject varchar(100) NOT NULL,PRIMARY KEY (id) ) E…

在 Amazon EKS 上部署生成式 AI 模型

导言 生成式 AI 正在改变企业的运作方式&#xff0c;并加快创新的步伐。总体而言&#xff0c;人工智能正在改变企业利用技术的方式。生成式 AI 技术包括微调和部署大型语言模型&#xff08;LLM&#xff09;&#xff0c;并允许开发人员访问这些模型以执行提示和对话。负责在 Kub…

【String、StringBuffer和StringBuilder的区别及使用场景】

String、StringBuffer和StringBuilder的区别及使用场景 1. String类是不可变的&#xff0c;一旦创建&#xff0c;就不能修改。每次对String进行操作&#xff08;如拼接、替换等&#xff09;&#xff0c;实际上是创建了一个新的String对象。由于String的不可变性&#xff0c;频繁…

使用 Python 的 Matplotlib 库来绘制简单的爱心图案

import matplotlib.pyplot as plt import numpy as npt np.linspace(0, 2*np.pi, 100) x 16 * np.sin(t)**3 y 13 * np.cos(t) - 5 * np.cos(2*t) - 2 * np.cos(3*t) - np.cos(4*t)plt.plot(x, y, r) plt.axis(equal) plt.fill(x, y, r) plt.show()这段代码首先导入了 Matpl…

【java中如何避免死锁及其分析和解决多线程环境下的死锁问题】

java中如何避免死锁及其分析和解决多线程环境下的死锁问题 死锁是在多线程环境中经常遇到的一种问题&#xff0c;可以通过以下方法来避免和解决死锁问题&#xff1a;死锁是多线程环境下常见的问题&#xff0c;它发生在两个或多个线程等待对方释放资源的情况下。为了避免死锁&am…

uniapp H5 touchstart touchend 切换背景会失效,或者没用

uniapp H5 touchstart touchend 切换背景会失效&#xff0c;或者没用 直接上代码 &#xff08;使用 class 以及 hover-class来设置样式&#xff09; class 设置默认的背景图或者样式 hover-class 来设置按下的背景图 或者样式 抬起 按下 <view class"mp_zoom_siz…

NRF24L01无线 2.4G射频模块(学习笔记)

一、市场上的NRF24L01模块有三种 二、模块的引脚接口 标准的4线SPI接口 三、寄存器操作命令以及寄存器地址 四、两个NRF24L01模块能够成功通信需要满足的条件 五、两个NRF24L01模块通信连接示意图

git远程仓库基本操作

目录 gitremote &#xff08;查看远程仓库&#xff09; git remote add [仓库名] [url] git clone [url]&#xff08;克隆远程仓库到本地&#xff09; git push [名][分支名]&#xff08;提交到远程仓库&#xff09;​编辑 git pull [名][分支名]从远程仓库拉取​编辑 注意操作…

人工智能是哪个专业

人工智能是一个以计算机科学为基础&#xff0c;由计算机、心理学、哲学等多学科交叉融合的交叉学科、新兴学科。其研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学&#xff0c;企图了解智能的实质&#xff0c;并生产出一种新的能以人类…

【个人博客搭建】Hexo安装部署

目录 一、本地构建Hexo (一) 安装前提 1. Node.js 2. Git 3. Hexo (二) 初始化Hexo 1. 初始化博客目录 2. 配置网站基本信息 (三) 主题配置 1. 选择主题 2. 下载主题 (四) 本地启动Hexo 1. 生成静态文件 2. 启动服务 二、部署 (一) 部署到Github Pages 1. 新建…

开源博客项目Blog .NET Core源码学习(8:EasyCaching使用浅析)

开源博客项目Blog使用EasyCaching模块实现缓存功能&#xff0c;主要是在App.Framwork项目中引用了多类包&#xff0c;包括内存缓存&#xff08;EasyCaching.InMemory&#xff09;、Redis缓存&#xff08;EasyCaching.CSRedis&#xff09;&#xff0c;同时支持多种序列化方式&am…

机器学习复习(4)——CNN算法

目录 数据增强方法 CNN图像分类数据集构建 导入数据集 定义trainer 超参数设置 数据增强 构建CNN网络 开始训练 模型测试 数据增强方法 # 一般情况下&#xff0c;我们不会在验证集和测试集上做数据扩增 # 我们只需要将图片裁剪成同样的大小并装换成Tensor就行 test_t…

【国产MCU】-CH32V307-GPIO控制:输入与输出

GPIO控制:输入与输出 文章目录 GPIO控制:输入与输出1、GPIO简单介绍2、驱动API介绍3、GPIO配置代码实现3.1 GPIO配置为输出3.2 GPIO配置为输入CH32V307的GPIO口可以配置成多种输入或输出模式,内置可关闭的上拉或下拉电阻,可以配置成推挽或开漏功能。GPIO口还可以复用成其他…

一文掌握SpringBoot注解之@Component 知识文集(8)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

人工智能(pytorch)搭建模型23-pytorch搭建生成对抗网络(GAN):手写数字生成的项目应用

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能(pytorch)搭建模型23-pytorch搭建生成对抗网络(GAN):手写数字生成的项目应用。生成对抗网络&#xff08;GAN&#xff09;是一种强大的生成模型&#xff0c;在手写数字生成方面具有广泛的应用前景。通过生成…

类和对象 第六部分 继承 第一部分:继承的语法

一.继承的概念 继承是面向对象的三大特性之一 有些类与类之间存在特殊的关系&#xff0c;例如下图&#xff1a; 我们可以发现&#xff0c;下级别的成员除了拥有上一级的共性&#xff0c;还有自己的特性&#xff0c;这个时候&#xff0c;我们可以讨论利用继承的技术&#xff0c;…

【前端素材】bootstrap3 实现地产置业公司source网页设计

一、需求分析 地产置业公司的网页通常是该公司的官方网站&#xff0c;旨在向访问者提供相关信息和服务。这些网页通常具有以下功能&#xff1a; 公司介绍&#xff1a;网页通常包含有关公司背景、历史、核心价值观和使命等方面的信息。此部分帮助访问者了解公司的身份和目标。 …

LabVIEW船舶自动识别系统

在现代航海领域&#xff0c;安全高效的船舶自动识别系统对于保障航行安全和提高船舶管理效率非常重要。介绍了利用LabVIEW软件开发的一个船舶自动识别系统&#xff0c;该系统通过先进的数据采集和信号处理技术&#xff0c;显著提升了传统自动识别系统的性能。 这个船舶自动识别…

代理IP在游戏中的作用有哪些?

游戏代理IP的作用是什么&#xff1f;IP代理软件相当于连接客户端和虚拟服务器的软件“中转站”&#xff0c;在我们向远程服务器提出需求后&#xff0c;代理服务器首先获得用户的请求&#xff0c;然后将服务请求转移到远程服务器&#xff0c;然后将远程服务器反馈的结果转移到客…

【lesson1】高并发内存池项目介绍

文章目录 这个项目做的是什么&#xff1f;这个项目的要求的知识储备和难度&#xff1f;什么是内存池池化技术内存池内存池主要解决的问题malloc 这个项目做的是什么&#xff1f; 当前项目是实现一个高并发的内存池&#xff0c;他的原型是google的一个开源项目tcmalloc&#xf…