快速入门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.mzph.cn/news/884097.shtml

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

相关文章

云原生Istio基础

一&#xff0e;Service Mesh 架构 Service Mesh&#xff08;服务网格&#xff09;是一种用于处理服务到服务通信的专用基础设施层。它的主要目的是将微服务之间复杂的通信和治理逻辑从微服务代码中分离出来&#xff0c;放到一个独立的层中进行管理。传统的微服务架构中&#x…

【网页布局技术】项目五 使用CSS设置导航栏

《CSSDIV网页样式与布局案例教程》 徐琴 目录 任务一 制作简单纵向导航栏支撑知识点1&#xff0e;合理利用display:block属性2&#xff0e;利用margin-bottom设置间隔效果3&#xff0e;利用border设置特殊边框 任务二 制作简单横向导航栏任务三 制作带图片效果的横向导航栏任务…

银河麒麟v10 xrdp安装

为了解决科技被卡脖子的问题&#xff0c;国家正在大力推进软硬件系统的信创替代&#xff0c;对于一些平时对Linux操作系统不太熟练的用户来讲提出了更高的挑战和要求。本文以银河麒麟v10 24.03为例带领大家配置kylin v10的远程桌面。 最近公司为了配置信创开发新购了几台银河麒…

什么是x86架构,什么是arm架构

什么是 x86 架构&#xff1f; x86 架构是一种经典的指令集架构&#xff08;ISA&#xff09;&#xff0c;最早由英特尔在 1978 年推出&#xff0c;主要用于 PC、服务器等领域。 它是一种复杂指令集计算&#xff08;CISC&#xff09;架构&#xff0c;支持大量的复杂指令和操作&…

客户的奇葩要求—在CAN网络的基础上加入了CAN_FD的节点

1&#xff1a;客户的奇葩要求 最近的工作中&#xff0c;遇到了一个有点奇葩的事&#xff0c;客户需要开发一个系统&#xff0c;我们负责其中的一个ECU&#xff0c;这个系统采取的是经典11bit ID的CAN网络。 今天突然提了一个要求&#xff0c;说要在网络中&#xff0c;加入支持…

4G 模组的 FTP 应用:技术科普

众所周知FTP协议包括两个组成部分&#xff0c;其一为FTP服务器&#xff0c;其二为FTP客户端&#xff0c;今天我将为大家带来一场4G 模组的 FTP 应用技术科普&#xff1a; 以低功耗模组Air780E核心板为例。 1、FTP 概述 FTP&#xff08;File Transfer Protocol&#xff0c;文件…

PAT甲级-1074 Reversing Linked List

题目 题目大意 给一个链表的头结点和总节点个数&#xff0c;以及k。每k个节点的链表都要翻转。 思路 链表可以用一个结构体数组来存储&#xff0c;先遍历一遍&#xff0c;过滤掉不在链表中的节点。然后将过滤好的节点放入res数组中&#xff0c;每k个元素用一次reverse()&…

44-RK3588s调试 camera-engine-rkaiq(rkaiq_3A_server)

在RK3588s平台上调试imx415 camera sensor 过程中&#xff0c;已经识别到了camera sensor ID&#xff0c;并且可以拿到raw图和isp处理后的图像&#xff0c;但是isp处理后的图像偏绿&#xff0c;来看查看后台服务发现rkaiq_3A_server没有运行&#xff0c;然后单独运行rkaiq_3A_s…

Python 变量在函数中的作用域

什么是局部变量&#xff1f; 作用范围在函数内部&#xff0c;在函数外部无法使用 什么是全局变量&#xff1f; 在函数内部和外部均可使用 如何将函数内定义的变量声明为全局变量&#xff1f; 使用global关键字&#xff0c; global变量 练习&#xff1a; 演示局部变量 #…

百数功能更新——表单提交支持跳转到外部链接并支持传参

百数的表单外链功能允许用户将表单以链接的形式分享给外部用户&#xff0c;外部用户无需登录或加入团队即可访问并填写表单。 本次更新的表单提交后跳转指定链接的功能&#xff0c;在支持跳转内部链接的基础上&#xff0c;支持用户在完成表单填写并提交后&#xff0c;自动跳转…

BSV区块链为供应链管理带来效率革命

​​发表时间&#xff1a;2024年10月10日 供应链管理是众多行业的重中之重&#xff0c;它确保了商品能够从制造商处顺畅地传递到消费者手中。然而&#xff0c;传统的供应链管理面临着许多挑战&#xff0c;包括缺乏透明度、延误、欺诈和协调上的低效率等等。 BSV区块链技术的出…

Linux基础(七):Linux文件与目录管理

Linux文件与目录管理 1.目录与路径1.1 cd1.2 pwd1.3 mkdir1.4 rmdir1.5 ls1.6 cp1.7 rm1.8 mv 2.可执行文件路径的变量&#xff1a;$PATH3.从字符串中获取目录名称和文件名称4.文件内容读取4.1 cat与tac4.2 nl4.3 more和less4.4 head与tail4.5 od 5 使用touch来改变文件的时间6…

C语言初阶:十一.代码调试技巧

❤欢迎各位大佬访问&#xff1a;折枝寄北-CSDN博客折枝寄北擅长C语言初阶,等方面的知识,折枝寄北关注python,c,java,qt,c语言领域.https://blog.csdn.net/2303_80170533?typeblog❤文章所属专栏https://blog.csdn.net/2303_80170533/category_12794764.html?spm1001.2014.300…

什么是aps排产管理软件?aps排产管理软件有什么用?最详细解释!

近几年&#xff0c;APS排产管理软件特别火&#xff0c;很多制造业企业都在谈论和使用它。不过&#xff0c;因为信息太多太杂&#xff0c;我们平时接收到的往往都是零零碎碎的介绍&#xff0c;很难全面了解它。所以&#xff0c;今天这篇文章就来给大家做个整合&#xff0c;把APS…

微信小程序25__实现卡片变换

先看效果图 实现代码如下&#xff1a; <view class"page" style"filter:hue-rotate({{rotation}}deg)"><view class"prev" catchtap"toPrev">《《《</view><view class"next" catchtap"toNext&q…

vue项目中如何在路由变化时增加一个进度条

在 Vue.js 项目中&#xff0c;使用路由&#xff08;如 Vue Router&#xff09;时&#xff0c;为了提升用户体验&#xff0c;你可能会想要在路由变化时显示一个进度条。这可以通过多种方式实现&#xff0c;其中一种流行的做法是使用第三方库&#xff0c;如 vue-loading-bar 或 n…

4款专业音频在线剪辑工具帮你开启创意之路。

音频在线剪辑工具能够为我们提供很大的便利&#xff0c;对于不管是专业的音乐制作人还是音频创作爱好者来说&#xff0c;都能借助一些音频编辑工具来充分发挥自己的创意。所以这一次&#xff0c;我要给大家介绍几个专业方便的音频剪辑工具。 1、福昕音频在线 直达链接&#x…

JK触发器(Quartus与Modelsim联合仿真)

JK触发器由于其灵活的逻辑功能&#xff0c;被广泛应用于数字电路设计中&#xff0c;如计数器、寄存器、序列信号发生器等。它可以通过改变J和K的输入来实现不同的逻辑操作&#xff0c;使得设计更加简洁高效。 在数字电子技术中&#xff0c;JK触发器的真值表是理解其工作原理和设…

Redis高频面试题

一、Redis有什么好处? 高性能:Redis是一个基于内存的数据存储系统,相比于传统的基于磁盘的数据库系统,它能够提供更高的读写性能。支持丰富的数据类型:Redis支持多种数据结构,包括字符串、哈希、列表、集合、有序集合等,这使得它可以用于多种不同的应用场景。持久化:Re…

Javaweb 实验7 JSP内置对象II实现购物车

实验七 JSP内置对象II 目的&#xff1a; 掌握JSP内置对象的使用。理解JSP的作用域掌握session&#xff0c;application对象的使用 实验要求&#xff1a; 完成实验题目要求提交实验报告&#xff0c;将代码和实验结果页面截图放入报告中 实验过程&#xff1a; 一、结合之前…