快速入门kotlin编程(精简但全面版)

注:本文章为个人学习记录,如有错误,欢迎留言指正。

目录

1. 变量

1.1 变量声明

1.2 数据类型

2. 函数

3. 判断语句

3.1 if

3.2 when语句

4. 循环语句

4.1 while

4.2 for-in

5. 类和对象

5.1 类的创建和对象的初始化

5.2 继承

5.3 构造函数

5.3.1 主构造函数

init结构体

5.3.2 次构造函数

5.3.3 无主构造

6. 接口

6.1 接口定义

6.2 接口的实现

7. 权限修饰符

8. 数据类和单例类

8.1 数据类

8.2 单例类

9. Lambda

9.1 集合的创建和使用

9.2 Lambda的使用

10. Java函数式接口的使用

11. 空指针检查机制

11.1 判空辅助工具

11.2 let函数

11.3 全局变量判空

12. 内嵌表达式

13. 函数的参数的默认值


1. 变量

kotlin没有;结尾

1.1 变量声明

//不声明类型(kotlin存在类型推导机制)
val a = 1  //final修饰,先使用val,有需要可变,再改成var
var b = 2  //无final修饰
// 声明类型用“:”
var c: Int = 1

优先使用val

1.2 数据类型

kotlin没有基本数据类型,使用对象类型 Int,Long,Short, Float,Double,Boolean,Char,Byte

2. 函数

fun main() {
}
fun sum(a: Int, b: Int): Int {return a + b
}
​
// 函数体只有一行代码:
fun sum(a: Int, b: Int): Int = a + b
​
// Kotlin存在类型推导,返回值类型也可省略
fun sum(a: Int, b: Int) = a + b

3. 判断语句

有if和when

3.1 if

if语句必须要有else,不然会报错

//返回最大值
fun max(a: Int, b: Int): Int {if (a > b)return aelsereturn b
}//if可以包含返回值,if语句的最后一行会作为返回值返回
fun max(a: Int, b: Int): Int {return if (a > b)aelseb
}
​
//写成一行
fun max(a: Int, b: Int) = if (a > b) a else b
 

3.2 when语句

eg:

//使用if实现
// Kotlin中==等价于Java的equals, 比较的是对象里的内容, 
// === 等价于Java的==,比较的为对象的引用。
fun getScore(n: String) = if (n == "A") "优秀"else if (n == "B") "良好"else "不好"
​
//使用when实现(when和if一样也可以有返回值)
fun getScore1(n: String) =when (n) {"A" -> "优秀""B" -> "良好"else -> "不好"}
when支持参数检查
fun checkType(num: Number) {when (num) {is Int -> println("Int")is Double -> println("Double")else -> println("others")}
}

when里面也可以不填形参

fun getScore2(n: String) =when {n == "A" -> "优秀"n == "B" -> "良好"else -> "不好"}

->后面也可以有很多行

fun getScore3(n: String) =when {n == "A" -> {println("打印一下:$n")"优秀"}n == "B" -> "良好"else -> "不好"}

4. 循环语句

有while和for-in。

while与java中的while没有区别,

for-in是对Java for-each的加强,

Kotlin舍弃了for-i的写法

4.1 while

和java一样

4.2 for-in

Java中的for-i在Kotlin中被舍弃

Java中的for-each被Kotlin加强变成了for-in

  • 什么是区间

    // 表示[0,10]区间
    val range = 0..10
    // 表示[0,10)区间
    val range1 = 0 until 10
  • for-in的使用

    for (i in 0..10) {println(i)  //0 ~ 10
    }
    for (i in 0 until 10) {println(i)  //0 ~ 9
    }
    for (i in  0 until 10 step 2) {println(i) //0,2,4,6,8
    }
    for (i in  10 downTo 1) {println(i) //10 ~ 1
    }

5. 类和对象

5.1 类的创建和对象的初始化

  • 创建Person类

class Person {var name = ""var age = 0fun pringInfo() {println(name + "的年龄是" + age)}
}
  • 在main方法中声明一个Person对象并调用printInfo方法

fun main() {//去掉了new关键字val person = Person()person.name = "lyx"person.age = 24person.pringInfo()
}

5.2 继承

Kotlin中任何一个非抽象类默认都是不可以被继承的,相当于Java中给类声明了final 关键字。

声明Student类继承Person,Kotlin中继承使用,后接父类的构造

Person类为final不可被继承,因此需借助open关键字

class Student : Person() {var id = ""var grade = 0fun study() {println(name + "是一个学生")}
}

5.3 构造函数

Kotlin将构造函数分 成了两种:主构造函数和次构造函数。

5.3.1 主构造函数

特点:没有函数体,直接定义在类名的后面

每个类默认都会有一个不带参数的主构造函数

class Student(val id: String, val grade: Int) : Person() {
}

也可以显式地给它指明参数

实例化的时候,必须传入构造函数中要求的所有参数

open class Person(val name :String,val age :Int) {
}

此时Student类就会报错,因为Person没有无参构造了

修改:

class Student( name :String, age :Int,val id: String, val grade: Int) : Person(name,age) {
}
init结构体

构造时需要进行特殊处理怎么办,Kotlin提供了init结构体,主构造的逻辑可在init中处理

open class Person(val name :String,val age :Int) {init {println("name is" + name)println("age is" + age)}
}
5.3.2 次构造函数

任何一个类只能有一个主构造函数,但是可以有多个次构造函数

次构造写在{}里面

有函数体

当一个类既有主构造函数又有次构造函数时,所有的次构造函数都必须调用主构造函数(包括间接调用)

class Student(name: String, age: Int, val id: String, val grade: Int) : Person(name, age) {// 三个参数// this关键字调用了主构造函数,this里面写默认值constructor(name: String, age: Int, id: String) : this("", 0, "", 0) {}
​// 无参构造//this关键字调用刚才定义的第一个次构造函数constructor() : this("", 0, "", 0) {}
}
5.3.3 无主构造

次构造可以调用父类构造super进行初始化,

但是次构造的参数在其他地方无法引用,

class Student : Person {// 次构造可以调用父类构造super进行初始化constructor(name: String, age: Int, id: String) : super(name, age) {}
​fun study() {// // name,age可使用println(name + "," + age + ",")// 使用number则会报错,若number是主构造的参数则可引用// println(number) 报红}
}

6. 接口

6.1 接口定义

和java类似

interface Study {fun study()fun eat()
}

6.2 接口的实现

在后面加逗号

class Student : Person ,Study{//Kotlin中使用override关键字来重写父类或者实现接口中的函数override fun study() {TODO("Not yet implemented")}
​override fun eat() {TODO("Not yet implemented")}
}

Kotlin支持接口方法的默认实现,

方法有方法体默认实现,则继承类无需必须实现此方法

interface Study {fun study()fun eat(){println("eat")}
}

7. 权限修饰符

Javakotlin
public所有类所有类(默认
protected当前类,子类,同一包下的类当前类,子类
default同一包的类(默认)x
private当前类当前类
internalx同模块下的类

8. 数据类和单例类

8.1 数据类

数据类则只处理数据相关,与Java Bean类似,通常需要实现其getsethashCodeequalstoString等方法

一行代码即可

若无data关键字,上述方法(hashCodeequalstoString)无法正常运行

当一个类中没有任何代码时,还可以将尾部的大括号省略。

data class UserBean(var id: Int, var name: String)

8.2 单例类

创建单例类,创建类型选择“Object”

object Singleton {fun test(){println("===")}
}

对应Java:

public final class Singleton {@NotNullpublic static final Sinfleton INSTANCE;
​public final void test() {String var1 = "===";System.out.println(var1);}
​private Sinfleton() {}
​static {Sinfleton var0 = new Sinfleton();INSTANCE = var0;}
}

使用:

fun main() {Singleton.test()
}

9. Lambda

9.1 集合的创建和使用

fun main() {//(1) List集合的创建// 常规创建val list = ArrayList<Int>()list.add(1)list.add(2)
​// lisrOf:不可变,只能查val list1 = listOf<Int>(1, 2, 3)// list1.add(4) //报错
​// mutableListOf:可变val list2 = mutableListOf<Int>(1, 2, 3)list2.add(4)
​// 循环for (value in list2) {println(value)}
​//(2) Set集合与List类似, 只是使用的是setOf()和mutableSetOf()val set = setOf<Int, String>(1 to "1", 2 to "2")
​//(3) Mapval map1 = HashMap<Int, String>()map1.put(1, "1")map1.put(2, "2")// 赋值map1[2] = "222"// 访问println(map1[2])println(map1.get(2))
​// 不可变val map2 = mapOf<Int, String>(1 to "1", 2 to "2")// map2[2] = "222" //报错
​// 可变val map3 = mutableMapOf<Int, String>(1 to "1", 2 to "2")map3[2] = "222"
​// 循环for ((key, value) in map3) {println("$key:$value")}
}

9.2 Lambda的使用

Lambda格式: { 参数名1: 参数类型, 参数名2:参数类型 -> 函数体 }

  • maxByOrNull():返回当前集合中...最大元素

  • map 映射:返回新集合,将集合中的元素映射成另一个值

  • filter过滤:返回新集合,将集合中的元素进行筛选

  • any:返回Boolean,集合中是否存在元素满足Lambda的条件,有则返回true,无则false

  • all:返回Boolean,集合中元素是否全部满足Lambda的条件,有则返回true,无则false

fun main() {val list = listOf<String>("aa", "dededed", "ajd", "aa")
​// 返回当前list中xx最大的元素// (1)不使用maxByOrNull函数var maxStr = ""for (str in list) {if (str.length > maxStr.length) {maxStr = str}}println("list中最大的str:" + maxStr)
​// (2)使用maxByOrNull函数// maxByOrNull或者maxBy是一个普通的方法,参数是Lambda参数var lambda = { str: String -> str.length }var maxString = list.maxByOrNull(lambda)println("list中最大的str:" + maxString)// 直接当成参数传递var maxString1 = list.maxByOrNull({ str: String -> str.length })// 如果lambda是方法的最后一个参数,参数可以提出来var maxString2 = list.maxByOrNull() { str: String -> str.length }// 如果只有一个参数,且是lambda参数,可以去掉方法的()var maxString3 = list.maxByOrNull { str: String -> str.length }// 有类型推导机制,也可以去掉参数类型var maxStrinf4 = list.maxByOrNull { str -> str.length }// 如果lambda只有一个参数,可以用it代替var maxString5 = list.maxByOrNull { it.length }
​// map映射(将集合中的每个元素都映射成一个另外的值)var newList1 = list.map { it.toUpperCase() }// filter过滤var newList2 = list.filter { it.length > 5 }// any 判断是否存在满足条件的元素var isAny = list.any { it.length > 5 }// all 判断是否全部满足条件var isAll = list.all { it.length > 0 }
}

10. Java函数式接口的使用

kotlin调用Java的方法,如果方法只接收一个Java单继承方法接口参数,可以使用函数式接口

单继承方法接口:就是接口中只有一个方法,比如Runnable接口:

public interface Runnable {void run();
}

在Java中启动一个线程:

new Thread(new Runnable() {@Overridepublic void run() {System.out.println("test");}
}).start();

在kotlin中:

// Kotlin摒弃了new,若想声明匿名内部类,必须使用object
Thread(object :Runnable{override fun run() {print("aaa")}
}).start()
​
// Runnable类中只有一个待实现方法,即使这里没有显式地重写run()方法,Kotlin也能自动明白Runnable后面的Lambda 表达式就是要在run()方法中实现的内容
Thread(Runnable {print("aaa")
}).start()
​
// 如果一个Java方法的参数列表中有且仅有一个Java单抽象方法接口参数,可以将接口名进行省略
Thread({print("aaa")
}).start()
​
// Thread只需一个参数,可省略()
Thread {print("aaa")
}.start()
​
// 与上类似的,click也使用上述方法
// button.setOnClickListener { println("test") }

11. 空指针检查机制

Kotlin把空指针异常的检查提前到了编译期,若空指针则编译期就会崩溃,避免在运行期出现问题

fun main() {// study(null)// 编译期就会报错
}
fun study(study: Study) {study.eat()
}

有特殊的需求,可能需要传递null参数,用?表示可以为空

fun main() {study(null)
}
// ? 表示参数可以为空,
fun study(study: Study?) {// 此时这里会报错study.eat()
}

如果参数可为空的话,则此对象调用的方法必须要保证对象不为空,上面代码没有保证,则报错,修改如下

fun main() {study(null)
}
// ? 表示参数可以为空,
fun study(study: Study?) {if (study != null) {study.eat()}
}

11.1 判空辅助工具

  • ?.

    表示?前面的不为空,才会执行.后面的方法,

    如果为空,就什么都不做

    fun study(study: Study?) {study?.eat()
    }
  • ?:

    表示?前的不为空,才返回?前的值,否则返回?后的值

    val c = a ?: b
    fun getTextLength(text: String?) = text?.length ?: 0
  • !!

    想要强行通过编译

    fun study(study: Study?) {study!!.eat()
    }

11.2 let函数

fun study(study: Study?) {// ?.保证了study不为空,才会执行let函数study?.let {it.eat() // it是studyit.drink()}
}

11.3 全局变量判空

全局变量即使做了判空,但是很可能被其他地方修改,还是不能保证没有空指针

var str: String? = null
fun demo() {//有问题if (str != null) {str.toUpperCase()str.reversed()}
}
fun demo1() {//使用let规避风险str?.let {it.toUpperCase()it.reversed()}
}

12. 内嵌表达式

在Java中使用的是+连接,kotlin中用$

fun main() {var name = "lyx"var age = 24println("姓名:$name,年龄:$age")
​// 复杂的: ${}var a = 2var b = 3println("a和b比较,${if (a > b) a else b} 大")
}

13. 函数的参数的默认值

给函数设定参数默认值,在很大程度上能够替代次构造函数

fun main() {// 正常传参myFun(1, "lisa")// 只传第一个,第二个参数有默认myFun(2)
​// 如果第一个参数有默认值,此时会报错,因为参数按照顺序放的// myFun1("lyx") //认为传入的是Int
​// kotlin使用键值对传参,不必按照参数定义的顺序来传参myFun1(name = "lyx")
}
// 第二个参数有默认值
fun myFun(id: Int, name: String = "nana") {println("$id:$name")
}
// 第一个参数有默认值
fun myFun1(id: Int = 4, name: String) {println("$id:$name")
}

之前的次构造函数(三个参数的),可以和主构造合并,只需要把不需要的参数加上默认值即可:

// 不使用默认参数
class Student1(name: String, age: Int, val number: String, val grade: Int) : Person(name, age) {constructor(name: String, age: Int, number: String) : this(name, age, number, 0) {}
}
// 使用默认参数
class Student2(name: String, age: Int, val number: String, val grade: Int = 0) : Person(name, age) {
}

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

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

相关文章

部署Leanote 蚂蚁笔记

目录 选择leanote的原因环境参考下载部署安装mongodb恢复mongodb数据mongodb创建用户编辑app.conf启动编写快捷启动脚本&#xff0c;start.sh stop.shmongodb的备份与恢复编写脚本(备份leanote)leanote自带的备份与恢复 配置pdf导出 选择leanote的原因 Leanote 虽然最后一次更…

MATLAB——入门知识

内容源于b站清风数学建模 数学建模清风老师《MATLAB教程新手入门篇》https://www.bilibili.com/video/BV1dN4y1Q7Kt/ 目录 1.帮助文档 2.注释 3.特殊字符 4.设置MATLAB数值显示格式 4.1.临时更改 4.2.永久改 5.常用函数 6.易错点 1.帮助文档 doc sum help sum e…

Qt Modbus初识

项目场景&#xff1a; 项目中&#xff0c;需要用modbus与温控器通信&#xff0c;控制面板的加热温度&#xff0c;Qt框架下已经提供了modbus模块 初识Modbus Modbus 协议是一种通信协议&#xff0c;而且是一种开放协议&#xff0c;因此广泛地用于在工业自动化系统中实现设备之…

jenkins搭建及流水线配置

1.安装docker curl https://mirrors.aliyun.com/repo/Centos-7.repo >> CentOS-Base-Aliyun.repomv CentOS-Base-Aliyun.repo /etc/yum.repos.d/yum -y install yum-utils device-mapper-persistent-data lvm2yum-config-manager --add-repo http://mirrors.aliyun.com/…

CSP/信奥赛C++刷题训练:经典前缀和例题(4):洛谷P3662:Why Did the Cow Cross the Road II S

CSP/信奥赛C刷题训练&#xff1a;经典前缀和例题&#xff08;4&#xff09; [USACO17FEB] Why Did the Cow Cross the Road II S 题目描述 The long road through Farmer John’s farm has N N N crosswalks across it, conveniently numbered 1 … N 1 \ldots N 1…N ( 1 …

spring容器的启动流程

spring容器的启动流程是一个面试中比较难答的题目。这块内容比较复杂&#xff0c;回答的时候如果想到什么回答什么&#xff0c;很容易把面试官绕晕。因此比较好的回答方式就是&#xff0c;先理清一个大致的启动流程&#xff0c;再根据面试官的问题细说小点。 这里我们从Annota…

RHCE——DNS域名解析服务器、selinux、防火墙

1、DNS简介 DNS &#xff08; Domain Name System &#xff09;是互联网上的一项服务&#xff0c;它作为将域名和 IP 地址相互映射的一个分布式 数据库&#xff0c;能够使人更方便的访问互联网。 DNS 系统使用的是网络的查询&#xff0c;那么自然需要有监听的 port 。 DNS 使…

使用和删除数据库

复习&#xff1a; 1. 查看所有的数据库 show databases; 2. 创建属于自己的数据库 create database 数据库名; create database if not exists 数据库名; create database if not exists 数据库名 character set utf8mb4 | collate utf8mb4_0900_ai_ci; 强烈建议在创建数…

Spring Boot集成iText实现电子签章

文章目录 一 电子签章1.1 什么是电子签章1.2 签名流程1.3 技术选型 二 实战2.1 生成数字证书2.2 生成印章图片2.3 PDF 签名 一 电子签章 1.1 什么是电子签章 基于《中华人民共和国电子签名法》等相关法规和技术规范&#xff0c;具有法律效力的电子签章一定是需要使用 CA 数字…

第5章 中级控件

第 5 章 中级控件 bilibili学习地址 github代码地址 本章介绍App开发常见的几类中级控件的用法&#xff0c;主要包括&#xff1a;如何定制几种简单的图形、如何使用几种选 择按钮、如何高效地输入文本、如何利用对话框获取交互信息等&#xff0c;然后结合本章所学的知识&…

Kubernetes:(四)kubectl命令

文章目录 一、kubectl命令1.查看版本信息 kubectl version2.列出 Kubernetes API 中所有可用的资源及其相关信息 kubectl api-resources3.配置kubectl自动补全 source <(kubectl completion bash)4.查看集群信息 kubectl cluster-info5.node节点查看日志 journalctl -u kube…

互联网人辞职的20条理由,你中了几条?

互联网行业压力大、内卷是众所周知的&#xff0c;想要辞职的念头往往只在一瞬间。 他们想要离职的理由虽然千奇百怪&#xff0c;但每一条都很扎心。 小码在网上搜集了互联网人想要辞职的20条理由&#xff0c;来看看你中了几条吧&#xff1f; 最能戳中你的“辞职理由”是什么呢…

https://huggingface.co/上的模型无法用linux服务器clone怎么办(只需要稍微改一下网址,就可以切换到镜像下载)

问题描述&#xff1a; 在ubuntu系统上&#xff0c;使用如下命令&#xff0c;克隆仓库&#xff0c;报无法访问错误&#xff1a; git clone https://huggingface.co/distilbert/distilroberta-base通用解决方案&#xff1a; 把下面部分更换&#xff1a; https://huggingface.…

使用传感器融合进行3D激光雷达点云运动补偿

此示例展示了如何通过融合来自全球定位系统 (GPS) 和惯性测量单元 (IMU) 传感器的数据来补偿由于自我车辆运动而导致的点云失真。此示例的目标是补偿点云数据中的失真并准确地重新创建周围环境。 文章目录 概述坐标系预处理激光雷达数据预处理 GPS 数据结合 GPS、IMU 和激光雷达…

请看,小白是如何三步速成ComfyUI?

前言 ComfyUI —三步速成秘籍— 嘿&#xff0c;小伙伴们&#xff01; 我是一个刚刚踏入GEO AI实验室的新鲜面孔&#xff0c; 一个对AI设计充满无限好奇的新手。 在这个充满创意和科技感的实验室里&#xff0c; 我只用了短短三个步骤&#xff0c; 就掌握了ComfyUI 。 你…

输电线路火灾隐患监测系统功能与应用是什么?

答&#xff1a;大家好&#xff01;今天我们来聊聊输电线路火灾隐患监测系统TLKS-PMG-DF。这款装置凭借其强大的功能和广泛的应用领域&#xff0c;正在成为电力巡检和山火防控的重要工具。下面&#xff0c;我们就来详细了解一下它的功能与应用吧&#xff01;这款装置配备了先进的…

《高频电子线路》 —— 高频谐振功放

文章内容来源于【中国大学MOOC 华中科技大学通信&#xff08;高频&#xff09;电子线路精品公开课】&#xff0c;此篇文章仅作为笔记分享。 高频谐振功放 主要目的就是功率放大以及高效率。 基本电路原理 高频谐振功放的基本电路&#xff0c;总体上也是由放大管和并联谐振回路…

Java阶段三01

第3章-第1节 一、知识点 maven的简介、安装和使用、仓库管理、项目构建、多模块项目、依赖管理 二、目标 学习了解什么是maven 能够配置maven 使用maven创建项目 掌握maven创建多模块项目的方式 掌握maven的依赖管理和项目构建 三、内容分析 重点 maven的安装和使用 …

【Docker】构建Linux云桌面环境

目录 一、说明 二、离线安装Docker 1&#xff09;将下载的包上传到服务器上去 2&#xff09;安装docker 3) 启动docker 4&#xff09;配置加速器 三、安装云桌面镜像 四、启动云桌面 方式一&#xff1a;docker命令直接运行 方式二&#xff1a;docker-compose方式 五…

【ArcGIS Pro实操第4期】绘制三维地图

【ArcGIS Pro实操第4期】绘制三维地图 ArcGIS Pro绘制三维地图-以DEM高程为例参考 如何使用ArcGIS Pro将栅格数据用三维的形式进行表达&#xff1f;在ArcGIS里可以使用ArcScene来实现&#xff0c;ArcGIS Pro实现原理跟ArcScene一致。由于Esri未来将不再对ArcGIS更新&#xff0c…