扩展函数和运算符重载

news2024/11/29 22:42:13

扩展函数和运算符重载

扩展函数

  • 扩展函数表示在不改变某个类的源代码的情况下,仍然可以打开这个类,向该类中添加新的函数
  • 为了能够更好的理解扩展函数的功能,先来思考一个问题:
  • 给定一个字符串,这个字符串由字母,数字,特殊符号组成,我们想要统计这个字符串当中字母的个数
  • 可以这样写:
/**
 * 定义一个单例类,在其中编写对应的方法 
 */
object StringUtil {
    fun letterCount(str: String) : Int {
        var count = 0
        for(char in str) {
            if(char.isLetter()) {
                count++
            }
        }
        return count
    }
}
  • 现在我们想要统计一个字符串的字母数量的时候只需要写出下面这类代码即可
val str = "ABC123&&abv"
println(StringUtil.letterCount(str))
  • 但是扩展函数可以帮助我们将letterCount()函数添加到String类当中
  • 扩展函数的语法结构:
fun ClassName.methodName(para1: Int, para2: Int) : Int {
    
}
  • 相比于定义一个普通的函数,定义扩展函数只需要在函数名的前面加上一个ClassName.的语法结构,这表示将该函数添加到指定的类当中了
  • 那么接可以将刚才定义的统计字符串字母数量的方法添加到String类当中了
  • 由于我们想要给String类添加一个扩展函数,所以我们需要先创建一个String.kt文件.
  • 文件名没有固定的要求,只是为了方便知道这个文件中都是哪个类的扩展函数,所以说给那个类添加扩展函数,就直接将扩展函数编写到这个类的同名.kt文件夹中
  • 通常来说扩展函数会定义成为顶层方法,因为这样可以让扩展函数用于全局的访问域.
  • 现在在String.kt文件当中编写扩展函数
fun String.letterCount() : Int{
    var count = 0
    for(char in this) {
        if(char.isLetter()) {
            count++
        }
    }
    return count
}
  • 注意两份代码的变化,我们将letterCount()方法定义成为了String类的扩展函数,那么在函数当中就自动拥有了该String实例的上下文.
  • 因此letterCount()函数就不需要再接受一个String类型的参数了,直接遍历this本身即可,因为现在this就代表着字符串本身
  • 定义好扩展函数之后我们代码就可以这样写了
println("ABC123&&abv".letterCount())
  • 这样子看上去就好像String类中自带了letterCount()方法一样.这个就是扩展函数的特点.

运算符重载

  • 运算符重载是Kotlin提供的一个比较有意思的语法糖概念
  • 在Kotlin当中允许我们对所有的运算发加上一些关键字做重载
  • 比如像+这个操作符,当使用两个数字进行+操作的时候代表对这个数字进行求和,当对两个字符串进行+操作的时候代码将这两个字符串进行拼接
  • 在Kotlin当中给我们提供了运算符重载机制,让我们能够实现对两个对象进行+操作
  • 但是我们在进行运算符重载的时候,一定要考虑它的意义性,比如我们让两个Student类进行相加好像没有什么意义,但是我们让两个Money类进行相加就说明我们想求出钱的总金额,这样才有意义
  • 运算符重载的基本语法:
  • 运算符重载使用的是operator关键字,只要在指定的函数前面加上operator关键字就可以实现运算符的重载了
  • 像+运算符的指定函数就是plus()函数
class obj {
    operator fun plus(obj: obj, obj: obj) : obj {
        //处理具体的相加逻辑
    }
}
  • 在上述的语法结构当中operator和plus都是固定不变的
  • 接收的参数和返回值是可以根据自己的逻辑进行变化
  • 上述代码就表示一个obj对象和另外一个obj对象可以进行相加,然后返回一个新的obj对象
  • 对应的调用方式如下:
val obj1 = obj()
val obj2 = obj()
val obj3 = obj1 + obj2
  • 虽然看上去比较神奇,但是实际上这是kotlin提供的一种语法糖,上述代码在编译的过程当中会自动转换成为:obj1.plus(obj2)的调用方式
  • 现在来实现一个两个Money对象进行相加的示例:
  • 首先定义Money类
class Money(val value: Int) {
    operator fun plus(money: Money) : Money {
        val sum = value + money.value
        return Money(sum)
    }
}
  • 在这里使用了operator关键字来修饰plus()函数,这是必不可少的,在plus()函数当中,我们将当前Money对象的value和参数中传递进来的Money的value进行相加,然后构造一个新的Money对象进行返回
  • 通过这样的操作,我们的Money对象就可以进行相加了
val money1 = Money(5)
val money2 = Money(10)
val money3 = money1 + money2
println(money3.value)
  • 上述代码打印出来的结果一定是15
  • 现在我们的+操作符可以进行Money对象之间进行相加了,当我们还想让+操作符和数字也能进行相加我们还可以继续重载
class Money(val value: Int) {
    operator fun plus(money: Money) : Money {
        val sum = value + money.value
        return Money(sum)
    }
     operator fun plus(value: Int) : Money {
        val sum = value + value
         return Money(sum)
    }
}
  • kotlin允许我们进行重载的运算符和关键字多达十几个,在下面的表当中就列举出了所有常用的可重载运算符和关键字对应的语法糖表达式,以及它们要被转换成的实际函数
  • 如果想要重载其中的某一种运算符或者关键字,只需要按照上述代码的写法进行编写即可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Oi8NRXh9-1669538864211)(C:/Users/zhengbo/%E6%88%91%E7%9A%84%E5%AD%A6%E4%B9%A0/Typora%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/%E5%AE%89%E5%8D%93/image-20221127164515782.png)]

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

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

相关文章

第十章 开源许可证

软件是一种著作,天然是拥有版权的。很多人会认为放在 Github 上的就是开源软件,既然放了源代码,我就可以随便使用了。其实版权法规定著作是禁止共享的,也就是说没有许可证的软件等于保留版权。虽然源代码公开了,但并不…

GUI编程--PyQt5--QLabel

文章目录QLabel 文本展示QLabel 图片展示QLCDNumberQProgressBarQErrorMessageQProgressDialogQLabel 文本展示 展示文本、富文本、图片、动画。 # 实例化 label QLabel(self) # 设置文本 label.setText("666") # 设置图片 label.setPixmap(QPixmap) label.resize…

[BUG] runtime network not ready: NetworkReady=false reason:NetworkPluginNotRead

1 背景 执行kubectl get node是发现节点是NotReady状态,接着执行kubectl describe node 节点名 详细查看NotReady状态原因如下: runtime network not ready: NetworkReadyfalse reason:NetworkPluginNotReady message:docker: network plugin is not r…

数据结构之线性表中的双向循环链表【详解】

前言: 嗯!昨天我们的无头单向非循环链表咱已经是可以顺利完成出来了的,今天我们就来看一下什么是有头双向循环链表,不要看着这个链表又双向又循环的就比单向不循环链表难,其实这个更加的简单哦!前提是你有…

SpringBoot SpringBoot 原理篇 1 自动配置 1.17 自动配置原理【3】

SpringBoot 【黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战(spring boot2完整版)】 SpringBoot 原理篇 文章目录SpringBootSpringBoot 原理篇1 自动配置1.17 自动配置原理【3】1.17.1 看源码了1.17.2 小结1 自动配置 1.…

【STA】(1)引言

目录 1. 纳米级设计 2. 什么是STA 3. 为什么要进行STA 4. 设计流程 5. 不同阶段的STA 6. STA的局限性 1. 纳米级设计 在半导体器件中,金属互连线通常被用来连接电路中的各个部分,进而实现整个芯片。随着制造工艺的进一步缩小,这些互连线…

【电源专题】案例:不导这颗MOS管的原因是在电路上不通用?

本案例发生在MOS管替代料导入时。正常情况下在替代料导入、部品导入的时候,我们需要查看规格书。怎么查找规格书可以看文章【电子通识】芯片资料查询方法 对于一些关键的信息我们要做对比,一般来说要通过列表进行对比。但因为不同的供应商的测试标准不同,有很多是很难对比的…

信号与系统2——LTI

信号与系统2——LTI一、Introduction1. Representation of LTI systems2. Significance of unit impulse二、DT-LTI:Convolution Sum1. Output2. Impulse response of LTI system H3. Convolution sum4. Convolution Sum Evaluation Procedure5. Sequence Convoluti…

Python 数据容器(1) - list(列表)

文章目录什么是数据容器?Python中的数据容器数据容器:list(列表)基本语法案例演示列表的下标(索引)列表常用操作list容器操作总结什么是数据容器? 一种可以容纳多份数据的数据类型,容…

算法学习 | 回溯算法之深度优先搜索常见题型练习

目录 岛屿的最大面积 电话号码的字母组合 二进制手表 组合总数 活字印刷 岛屿的最大面积 题目链接:leetcode-695.岛屿的最大面积 示例 输入:grid [[0,0,1,0,0,0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,1,1,0,1,0,0,0,0,0,0,0,0],[0,…

线程“八锁“ synchronized到底是对哪个对象加锁?

线程"八锁" synchronized到底是对哪个对象加锁? 习题一 class Number{public synchronized void a(){System.out.println("1");}public synchronized void b(){System.out.println("2");} } public class TestBlock {public static void main(…

从Zemax OpticStudio导入光学系统

摘要 ZemaxOpticStudio是一款广泛使用的光线追迹软件。VirtualLab Fusion可以从Zemax OpticStudio导入光学系统,包括完整3D位置信息和镜片玻璃。导入后,光学系统的结构数据将显示为单独的表面或可以组合成VirtualLab Fusion中的组件。VirtualLab Fusion可…

docker入门(一):在centOS虚拟机上安装docker

索引CentOS虚拟机安装1.下载CentOS镜像问题1-报错“您已输入用户名,客户机操作系统将保留此用户名”2.根据docker官方指导进行安装1.卸载旧版本(初次安装可以忽略)2.确保能联网后下载前置软件包3.设置镜像库(阿里版)4.…

CLIP后续--LSeg,GroupViT,ViLD

这个博客开了有两个月,一直没写成,最近封寝给它完成~躺平第三天 CLIP应用领域概览: 1. LSeg 原论文地址:https://arxiv.org/abs/2201.03546 代码:https://github.com/isl-org/lang-seg 这个图就很清楚的说明了zero…

mysql数据库管理

目录 一、MySQL数据库管理 1、库和表 2、常用的数据类型 3、char和varchar区别 二、查看数据库结构 三、SQL语句 1、SQL语句分类: 四、创建及删除数据库和表 五、管理表中的数据记录 六、修改表名和表结构 七、自增 八、填充 九、克隆表 十、清空表&am…

信号与系统1——Signals and Systems

信号与系统1——Signals and Systems一、Introduction1. Signals and Systems信号与系统(1) Signal信号(2) System系统2. Classification of Signals信号的分类(1) Continuous-time & discrete-time1) Continuous-Time signal连续时间信号2) Discrete-Time signal离散时间信…

【Hack The Box】linux练习-- Passage

HTB 学习笔记 【Hack The Box】linux练习-- Passage 🔥系列专栏:Hack The Box 🎉欢迎关注🔎点赞👍收藏⭐️留言📝 📆首发时间:🌴2022年9月7日🌴 &#x1f36…

浅析数据仓库和建模理论

第一章 认识数据仓库 1.1 数据仓库概念 数据仓库,英文名称为 Data Warehouse,可简写为 DW 或 DWH。数据仓库,是为企业所有级别的决策制定过程,提供所有类型数据支持的战略集合。它是单个数据存储,出于分析性报告和决…

BDD - SpecFlow SpecRun Web UI 多浏览器测试

BDD - SpecFlow & SpecRun 一个 Cases 匹配多个浏览器引言方案SpecFlow Runner profiles实现被测 Web Application创建一个 Class Libary 项目添加 NuGet PackagesSpecFlow & SpecRun 包添加 Selenium包其它包创建 Feature 文件配置 Default.srprofileDefault.srprofil…

MySQL的概念

MySQL的概念一.数据库的基本概念1、数据(Data)2、表3、数据库4、数据库管理系统(DBMS)4.1 关系数据库4.2 非关系型数据库 NoSQL5、数据库系统6、访问数据库的流程二.数据库系统发展史1.第一代数据库2.第二代数据库3.第三代数据库三…