Kotlin面向对象基础使用方法(继承、接口、Lambda、空指针检查机制等)
三、面向对象
1、继承
1.1 open改变类的继承属性
在kotlin设计时默认所有的非抽象类是无法被继承的,如果想要使得一个非抽象类可以被继承,我们需要使用open关键字。
open class Person {var name ="";var age = 0;fun eat() {println(name + " is eating. He is " + age +" years old.")}
}
同理如果类中的方法需要继承也需要使用open
关键字
1.2 主构造函数与次构造函数
主构造函数:
- 主构造函数的特点是没有函数体,直接定义在类名后面即可。
- 主构造函数只能有一个,而且通常用于初始化类的属性,以及执行与类的整体初始化相关的操作。
- 主构造函数的参数可以带有默认值,从而允许创建对象时省略某些参数。
我们使用init
关键字编写主构造函数的逻辑
class Person(val name: String, val age: Int) {init {println("Person对象已创建,姓名:$name,年龄:$age")}
}
注意:
在主构造函数中声明val、var
的字段会自动成为该类的字段,这样就会导致和父类中同名的字段冲突。如果不使用val、var
关键字数据的作用域仅限定在主构造函数中。
副构造函数:
- 副构造函数是类中的额外构造函数,可以有多个,它们用
constructor
关键字声明。 - 副构造函数通常用于提供不同的构造方式,允许使用不同的参数组合来创建对象。
class Person(val name: String, val age: Int) {// 主构造函数init {println("Person对象已创建,姓名:$name,年龄:$age")}// 副构造函数1,接受姓名参数constructor(name: String) : this(name, 0) {println("副构造函数1被调用")}// 副构造函数2,接受年龄参数constructor(age: Int) : this("未知姓名", age) {println("副构造函数2被调用")}
}
1.3 继承的格式
格式:
class 新的类名(无/参数) : 被继承类(无/参数){}
重写类的继承方法需要关键字override
,并且被重写的方法需要有open
关键字修饰。
open class Person(val name:String,val age:Int) {open fun eat() {println(name + " is eating. He is " + age +" years old.")}}class Student(val sno:String,val age1:Int) : Person(sno,age1){override fun eat(){println("$name Dont $age")}
}fun main(){var i = Student("JAck",19)i.eat()
}
kotlin规定,当一个类既有主构造函数又有次构造函数,所有的次构造函数都必须调用主构造函数。
open class Person(val name:String,val age:Int) {fun eat() {println(name + " is eating. He is " + age +" years old.")}}class Student(val sno:String,val grade:Int,name: String,age: Int) : Person(name,age){//通过次构造函数调用主构造函数constructor(name: String,age: Int) : this("",0,name,age){}constructor() : this("",0)
}fun main(){var i = Student("JAck",19)var p = Student("abs",1,"jaks",1)i.eat()
}
在这里this
的用法是什么??
在这个类中,this
关键字的使用是为了调用不同构造函数的目的。
具体来说,这个Student
类具有以下构造函数:
- 主构造函数:
Student
类的主构造函数接受四个参数,分别是sno
、grade
、name
和age
。这些参数用于初始化类的属性,其中sno
和grade
是继承自Person
类的属性,而name
和age
是本类的属性。 - 第一个副构造函数:这个副构造函数接受两个参数,即
name
和age
,它通过使用this
关键字来**调用了主构造函数,**传递了空字符串""
和0
作为参数,这意味着它将调用主构造函数以初始化sno
和grade
属性,并且将传递的name
和age
参数用于初始化本类的属性。 - 第二个副构造函数:这个副构造函数不接受任何参数,它同样通过使用
this
关键字来**调用了第一个副构造函数,**传递了空字符串""
和零0
作为参数,从而也会触发调用主构造函数,并且初始化本类的属性。
2、接口
接口的基本用法和java一致,但是在kotlin中允许代码对接口中的方法进行默认实现。
interface Study{fun readBooks()fun doHomework(){println("ANT")}
}
3、数据类——Java中toString、equals、hashCode的省略
在kotlin中我们不必写这些繁琐的方法,直接使用关键字data即可,代码如下:
//使用data修饰
data class Cellphone(val brand: String,val price: Double) {
}fun main(args: Array<String>) {val cellphone1 = Cellphone("Samsung",1299.99)val cellphone2 = Cellphone("Samsung",1299.99)println(cellphone1)println( "cellphone1 == cellphone2 ?? "+(cellphone1 == cellphone2))
}
Kotlin会根据主构造函数中的参数帮你将equals(),hash Code(),toString()等固定且无实际逻辑意义的方法自动生成。
4、单例类——object关键字
在kotlin中创建一个单例类的方式极其简单,只需要将class
关键字改为object
关键字即可。
object Singleton {fun singletonTest(){println("This is a OneInstance")}
}
此时Singleton就是一个单例类了,我们可以在这个类中直接编写需要的函数。
可以看出在Kotlin中我们不需要私有化构造函数。
5、Lambda编程
5.1 集合的创建和遍历
5.11 List集合
5.111、listOf
一般情况下我们需要使用这种方式初始化:
val list = ArrayList<String>()list.add("Apple")list.add("Banana")list.add("Orange")
在kotlin中提供了一个内置的listOf
函数来简化初始化集合的写法。
val list = listOf<String>("Apple","Banana","Orange")
当然我们也可以使用for-in遍历这个集合,并且Kotlin会自动补全fruit
的类型。
for(fruit in list){println(fruit)}
不过需要注意的是使用listOf
创建的集合是一个不可变集合
,就是该集合只能用于读取操作。
为什么会不可修改呢?
通过源码我们发现底层是数组的存储方式这样就能解释listOf`创建的集合只能用于读写操作了,同样他的查询效率也是比较高的。
5.112、mutableListOf
使用mutableListOf
创建的集合是一个可变集合,可以对集合进行增删改查的操作。
查看源码可以发现创建的是一个Arraylist类型的集合。使用链表的形式存储。
5.12 Set类型
Set集合的用法基本上和List集合的一样,只不过创建集合的方式变成了setOf()
和mutableSetof()
5.13 Map类型
Map类的的基本创建方法和Java中是一致的。
val map = HashMap<String, Int>()map.put("Apple",1)map.put("Banana",2)map.put("Orange",3)
当然kotlint
在Map中同样提供了mapOf
和mutableMapOf
方法用于集合的创建。Kotlin 的 mapOf
和 mutableMapOf
在底层都使用哈希表(Hash Table)作为存储结构,mapOf
是数组存储,mutableMapOf
是LinkedHash
val map = mapOf("Apple" to 1,"Banana" to 2,"Orange" to 3)for((fruit,number) in map){println(fruit + number)
}
需要注意的时这里的to不是关键字而是一个infix函数。
Kotlin 中,infix函数允许你以更自然的方式使用中缀表示法调用函数。
5.2 集合函数式API
5.21 Lambda表达式的优化过程
{参数名:参数类型 -> 函数体}
val maxLengthFruit = list.maxBy({fruit:String -> fruit.length})
- Kotlin规定当Lambda参数是函数的最后一个参数时,可以将Lambda表达式移到括号外面
val maxLengthFruit = list.maxBy(){fruit:String -> fruit.length}
- 如果Lambda表达式是函数的唯一个参数,还可以将括号省略。而且kotlin具有出色的推到机制,我们还可以不声明参数类型。
val maxLengthFruit = list.maxBy{fruit -> fruit.length}
- 并且当Lambda表达式参数列表只有一个参数时,也不必要声明参数名。可以使用
it
代替
val maxLengthFruit = list.maxBy{it.length}
5.22 常用API
-
计算最大长度:maxBy{it.length}
-
小写转大写:map { it.uppercase() }
-
过滤集合中的数据:filter函数
val newList = list.filter { it.length > 5 }.map { it.uppercase() }
-
判断集合是否存在至少一个元素满足要求:any.{}
-
判断集合是否所有元素都满足要求:all.{}
val anyResult = list.any{it.length >= 5} val allResult = list.all { it.length >= 10 }
6、空指针检查机制
Kotlin将空指针检查机制提到了编译时期,它默认所有的参数和变量都是非空的。
那么我们应该如何表示一个可空的类型呢?
6.1 ?
很简单在类名后加一个?代表可以是非空整形,例如:
I n t ? Int? Int?
但是此时就可能出现潜在的空指针异常风险,那么我们应该如何解决呢?Kotlin提供了一个辅助判空工具——?.。
6.2 辅助判空工具
6.2.1 ?.
例如这段代码:
if(A != null){A.do()
}
可以简化为这样的形式:
A?.do()
6.2.2 ?:
例如这段代码:
if(A != null){A
}else{B
}
可以简化为以下形式:
Val c = A ?: C
左边表达式不为空就返回左边的值,否则返回右边的值。
6.2.3 非空断言工具——!!
Kotlin的这种检查机制在某些情况下也会出现问题,例如:
此时是无法通过编译的,因为uppercase无法知道content不是空值。
此时就需要一种断言工具——!!
val upString = content!!.uppercase()
这是一种有风险的写法,意在告诉Kotlin,这里对象肯定不是空你不需要帮我检查空指针。
6.2.4 let辅助工具
这个函数提供了函数式API的编程接口,并将原始对象作为参数传递到Lambda表达式中。
obj.let{ obj1 ->//业务逻辑}
在这里,obj和obj1实际上是同一个对象。
如使用let修改这一段代码:
fun doStuday(study: Study?) {study?.doHomework()study?.readBooks()
}
修改结果如下:
fun doStuday(study: Study?) {study?.let {it.readBooks()it.doHomework()}
}
let
是可以处理全局变量的判空问题但是if
不行,因为if可以导致别的线程修改了这个全局变量。
相关文章:

Kotlin面向对象基础使用方法(继承、接口、Lambda、空指针检查机制等)
三、面向对象 1、继承 1.1 open改变类的继承属性 在kotlin设计时默认所有的非抽象类是无法被继承的,如果想要使得一个非抽象类可以被继承,我们需要使用open关键字。 open class Person {var name "";var age 0;fun eat() {println(name …...
Android USB电源管理
The USB peripheral detects the lack of 3 consecutive SOF packets as a suspend request from the USB host. 1 驱动shutdown顺序 系统关机或重启的过程中,会调用设备驱动的shutdown函数来完成设备的关闭操作,有需要的设备可以在驱动中定义该函数。其…...

YOLO目标检测——路标数据集+已标注voc和yolo格式标签下载分享
实际项目应用:自动驾驶、视频监控和安防、物体识别和分类、城市规划和地理信息系统等等数据集说明:YOLO路标目标检测数据集,真实场景的高质量图片数据,数据场景丰富,图片格式为jpg,共900张图片,…...
Item-Based Recommendations with Hadoop
Mahout在MapReduce上实现了Item-Based Collaborative Filtering,这里我尝试运行一下。 安装Hadoop 从下载Mahout并解压 准备数据 下载1 Million MovieLens Dataset,解压得到ratings.dat,用 sed ‘s/:😦[0-9]{1,}):😦…...

基于物理层网络编码的相位同步算法matlab仿真
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ..........................................................................%数据长度 Len…...

数据结构——七大排序[源码+动图+性能测试]
本章代码gitee仓库:排序 文章目录 🎃0. 思维导图🧨1. 插入排序✨1.1 直接插入排序✨1.2 希尔排序 🎊2. 选择排序🎋2.1 直接选择排序🎋2.2 堆排序 🎏3. 交换排序🎐3.1 冒泡排序&#…...

G. The Morning Star
Problem - G - Codeforces 思路:想了挺长时间的,一直没想到一个简便的方法在瞎搞。我们发现对于某个点来说,其他的点如果能够跟他匹配,那么一定在这8个方向上,而同时这8个方向其实对应这4条直线,假设点为(x…...

电池的健康状态 SOH 估计
电池的健康状态 SOH 估计 SOH(State of Health)估计通常用于描述电池的健康状态,即电池当前容量与初始容量的比值。 一种常见的SOH估计方法是基于经验的电池寿命预测方法,包括循环周期数法、安时法与加权安时法、面向事件的老化…...
Web 安全之 Permissions Policy(权限策略)详解
什么是 Permissions Policy(权限策略)? Permissions Policy 为 web 开发人员提供了明确声明哪些功能可以在网站上使用,哪些功能不能在网站上使用的机制。可以设置一组策略,用于限制站点代码可以访问的 API 或者修改浏…...
【黄啊码】nginx如何设置php运行的
禁止访问 PHP 脚本可以通过 Nginx 服务器配置中的多种方式来实现。以下是其中的一些常见方法,您可以根据实际需求选择合适的方式: 1 禁用 PHP 解析: 在 Nginx 配置中,确保 PHP 脚本无法被解析,从而禁止 PHP 执行。 lo…...

无涯教程-JavaScript - ISPMT函数
描述 ISPMT函数计算在特定投资期间支付的利息。提供此功能是为了与Lotus 1-2-3兼容。 语法 ISPMT (rate, per, nper, pv)争论 Argument描述Required/OptionalRateThe interest rate for the investment.RequiredPerThe period for which you want to find the interest, an…...
LeetCode 面试题 03.05. 栈排序
文章目录 一、题目二、C# 题解 一、题目 栈排序。 编写程序,对栈进行排序使最小元素位于栈顶。最多只能使用一个其他的临时栈存放数据,但不得将元素复制到别的数据结构(如数组)中。该栈支持如下操作:push、pop、peek 和…...

构建微服务项目时启动网关服务失败的解决方案
启动网关服务时报“Unable to create the temporary folder: C:\WINDOWS\TEMP\/nio-file-upload”错误。 代码与之前没有任何变化,但就是启动不了,观察错误意思大概是不能创建临时文件夹:C盘下的WINDOWS下的TEMP目录下的nio-file-upload这个东…...

零基础教程:使用yolov8训练无人机VisDrone数据集
1.准备数据集 1.先给出VisDrone2019数据集的下载地址: 链接:https://pan.baidu.com/s/1e2Q0NgNT-H-Acb2H0Cx8sg 提取码:31dl 2.将数据集VisDrone放在datasets目录下面 2.数据集转换程序 1.在根目录下面新建一个.py文件,取名叫…...
【Mysql专题】使用Mysql做排行榜,线上实例
背景 我们这里有个需求,对存量用户的余额做排行处理,这个实现方式很多,这边介绍的是,通过Mysql直接实现,将排名也直接返回出来。 我知道大家在网上能找到一大把这种实例,我在这里可不是【重复造轮子】。我…...

matlab数据处理: cell table array+datetime
原数据文件.csv matlab xlsread(filename{i},B2:T2881) 会同于Excel最多1048576行 舍弃 a{1,i} xlsread(filename{i},‘B2:T2881’);%读取excel文件,选定区域’B2:G2881’ readcell(filename{i},Range,E2:M2881) 会全部读取 优选 对于日期 yyyy-MM-dd HH:mm:ss.000 matlab cel…...

如何应用运营商大数据精准营销?
如何应用运营商大数据精准营销? 越来越多的企业逐渐觉察到运营商大数据所带来的商业价值,精准营销也被他们用的越来越娴熟。那么,企业的大数据精准营销该如何应用呢?想必是很多资源有限的中小型公司最想了解的。 一 数据驱动运营…...

AJAX学习笔记5同步与异步理解
AJAX学习笔记4解决乱码问题_biubiubiu0706的博客-CSDN博客 示例 前端代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>演示AJAX同步和异步</title> </head> <body> <script…...
911面试
WebPack分包 webpack分包 ts泛型 ts泛型 优化if-else和switch 优化if-else 左侧固定,右侧自适应 左侧固定,右侧自适应...

【Java基础篇 | 面向对象】—— 继承
个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【JavaSE_primary】 本专栏旨在分享学习JavaSE的一点学习心得,欢迎大家在评论区讨论💌 继承允许一个类继承另一个…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...

LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...