Kotlin快速入门系列9

news2024/9/22 17:37:48

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函数,返回类型为Any
    fun 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 = WebSite
    var s2 = WebSite
    s1.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 = WebSite
    site.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.coloradmin.cn/o/1421419.html

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

相关文章

Java 开发环境 全套包含IDEA

一、JDK配置 1.下载 JDK Builds from Oracle 去这边下载open JDK 2.JDK环境变量配置 按win&#xff0c;打开设置 找到环境变量编辑 这边输入的是你下载的那个JDK的bin的路径 检擦配置是否正确在cmd中输入 二、IDEA安装配置 1.下载&#xff08;社区版&#xff09; JetBrai…

干货 | 大模型在图数据分析、推荐系统和生物科学中的综合应用

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 图机器学习、推荐系统与大语言模型的融合正成为新的前沿热点。图机器学习通过利用图结构数据&#xff0c;能够有效地捕捉和分析复杂关系和模式。同时&#xff0c;推荐系统正逐步成为我们日常生活的一部分&#…

华为——NGFW Module安装在集群交换机上,二层双机负载分担部署,交换机重定向引流

NGFW Module安装在集群交换机上&#xff0c;二层双机负载分担部署&#xff0c;交换机重定向引流 业务需求 如图1所示&#xff0c;两台交换机集群组网&#xff0c;两块NGFW Module分别安装在两台交换机的1号槽位组成双机负载分担组网。NGFW Module工作在二层&#xff0c;也就是…

走进水稻种植教学基地可视化:科技与农业知识的完美结合

随着科技的不断发展&#xff0c;农业领域也在不断创新和进步。水稻种植教学基地可视化系统是一种基于现代信息技术手段的教学方式&#xff0c;通过虚拟现实、3D建模等技术&#xff0c;将水稻种植的全过程进行模拟和展示。这种教学方式打破了传统农业教学的局限性&#xff0c;使…

腾讯云部署vue+node项目

文章目录 一、安装宝塔二、vue项目部署三、node项目部署 前言: 关于项目部署,一开始也是找了很多资料,费了点时间,所以记录一下。希望能对各位有所帮助。 一、安装宝塔 1.首先在控制台,进入云服务器的终端界面 2.输入命令和密码获取权限,并且安装宝塔界面 yum install -y w…

关于在Tkinter + Pillow图片叠加中出现的问题

这段时间我一直在尝试对多图层图片进行一个叠加的操作&#xff0c;想用tkinter实现出来&#xff0c;先看错误 这里我其实已经选择了图片&#xff0c;但是发现是ValueError&#xff0c;我尝试断点检测但是也无动于衷&#xff0c;因为设置变量检测的时候发现变量并没有错误&…

Opencv——图片卷积

图像滤波是尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性。 线性滤波是图像处理最基本的方法,它允许我们对图像进行处理,产生很多不同的效果。首先,我们需要一个二…

大数据学习之Redis,十大数据类型的具体应用(三)

目录 3.7 Redis位图&#xff08;bitmap&#xff09; 概念 需求 是什么 说明 能干嘛? 基本命令 3.7 Redis位图&#xff08;bitmap&#xff09; 概念 由0和1状态表现的二进制位的bit数组 需求 用户是否登陆过&#xff1f;Y / N 广告是否被点击过&#xff1f; 钉钉打…

【机器学习】常见算法详解第2篇:KNN之kd树介绍(已分享,附代码)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论机器学习算法相关知识。机器学习算法文章笔记以算法、案例为驱动的学习&#xff0c;伴随浅显易懂的数学知识&#xff0c;让大家掌握机器学习常见算法原理&#xff0c;应用Scikit-learn实现机器学习算法的应用&#xff0…

外汇监管牌照解析:确保交易安全与合规性

外汇交易中&#xff0c;资金安全与平台监管是大家最关心的话题。监管是评估外汇经纪商是否值得信赖、是否具备相关资质的关键依据&#xff0c;因此选择一家拥有海外合法监管的经济商至关重要。 那么&#xff0c;今天我们就来聊聊全球权威的几大监管机构 — FCA、ASIC、NFA、FSA…

linux -- 内存管理 -- 页面分配器

linux内存管理 为什么要了解linux内存管理 分配并使用内存&#xff0c;是内核程序与驱动程序中非常重要的一环。内存分配函数都依赖于内核中一个非常复杂而重要的组件 - 内存管理。 linux驱动程序不可避免要与内核中的内存管理模块打交道。 linux内存管理可以总体上分为两大…

Tensorflow2.0笔记 - Tensor的限值clip操作

本笔记主要记录使用maximum/minimum,clip_by_value和clip_by_norm来进行张量值的限值操作。 import tensorflow as tf import numpy as nptf.__version__#maximum/minimumz做上下界的限值 tensor tf.random.shuffle(tf.range(10)) print(tensor)#maximum(x, y, nameNone) #对…

数据可视化 pycharts实现地理数据可视化(全球地图)

自用版 紧急整理一点可能要用的可视化代码&#xff0c;略粗糙 以后有机会再改 requirements&#xff1a; python3.6及以上pycharts1.9 数据格式为&#xff1a; 运行结果为&#xff1a; import pandas as pd from pyecharts.charts import Map, Timeline from pyecharts im…

Unity3D正则表达式的使用

系列文章目录 unity工具 文章目录 系列文章目录前言一、匹配正整数的使用方法1-1、代码如下1-2、结果如下 二、匹配大写字母2-1、代码如下1-2、结果如下 三、Regex类3-1、Match&#xff08;&#xff09;3-2、Matches()3-3、IsMatch&#xff08;&#xff09; 四、定义正则表达式…

TypeScript 学习笔记(Day2)

「写在前面」 本文为 b 站黑马程序员 TypeScript 教程的学习笔记。本着自己学习、分享他人的态度&#xff0c;分享学习笔记&#xff0c;希望能对大家有所帮助。推荐先按顺序阅读往期内容&#xff1a; 1. TypeScript 学习笔记&#xff08;Day1&#xff09; 目录 3 TypeScript 常…

Java-并发高频面试题

1.说一下你对Java内存模型&#xff08;JMM&#xff09;的理解&#xff1f; 其实java内存模型是一种抽象的模型&#xff0c;具体来看可以分为工作内存和主内存。 JMM规定所有的变量都会存储再主内存当中&#xff0c;再操作的时候需要从主内存中复制一份到本地内存&#xff08;c…

面试题:MySQL数据库索引失效的10连问你学会了吗?

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通Golang》…

【2024.1.30练习】李白打酒加强版(25分)

题目描述 题目思路 在最多数据的情况下&#xff0c;有100个店100朵花&#xff0c;总情况为的天文数字&#xff0c;暴力枚举已经不可能实现&#xff0c;考虑使用动态规划解决问题。最后遇到的一定是花&#xff0c;所以思路更倾向于倒推。 建立二维数组&#xff0c;容易联想到为…

vxe-table从2.0升级到3.0,vxe-table-plugin-virtual-tree虚拟滚动失效

问题&#xff1a;系统一直使用的vxe-table2.0&#xff0c;vxe-table2.0不支持树的虚拟滚动&#xff0c;为了解决这个问题&#xff0c;引入了vxe-table-plugin-virtual-tree插件&#xff0c;现在系统vxe-table升级3.0&#xff0c;vxe-table-plugin-virtual-tree的虚拟滚动失效了…

【MySQL】学习如何通过DQL进行数据库数据的条件查询

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-63IIm2s5sIhQfsfy {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…