- 一、Kotlin简介
- 1.Kotlin相比于Java的优势
- 2.Kotlin的工作原理
- 二、运行Kotlin代码的三种方式
- 1.IntelliJ IDEA
- 2.在线运行网站 [https://play.kotlinlang.org/](https://play.kotlinlang.org/)
- 3.Android Studio
- 三、Kotlin基本语法
- 1.变量
- 1.1 定义变量:只允许在变量前声明两种关键字,val与var。
- 1.2 kotlin类型推导机制
- 1.3 Java与Kotlin数据类型对照表
- 2.函数
- 2.1 定义函数的语法规则
- 2.2 单行代码函数的语法糖
- 3.逻辑控制
- 3.1 if条件语句
- 3.2 when条件语句
- 3.2.1 精确匹配
- 3.2.2 类型匹配
- 3.3 while循环语句
- 3.4 for-in循环语句
- 3.4.1 区间
- 4.面向对象编程
- 4.1 类与对象
- 4.2 继承与多态
- 4.2.1 继承:open与冒号关键字
- 4.2.2 主、次构造函数
- 4.3 接口
- 4.4 数据类
- 4.5 单例类
- 5.Lambda编程
- 5.1 创建集合
- 5.2 Lambda表达式
- 5.3 集合的函数式API
- 5.4 Java函数式API
- 6.空指针检查
- 空指针检查
- 可空类型系统
- 判空辅助工具
- 7.Kotlin 中的小魔术
- 7.1 字符串内嵌表达式
- 7.2 函数的参数默认值
- 7.3 字符串内嵌表达式
2011年,JetBrains发布了Kotlin的第一个版本,并在2012年将其开源。
2016年Kotlin发布了1.0正式版,代表着Kotlin语言已经足够成熟和稳定了,并且JetBrains也在自家的旗舰IDE开发工具IntelliJ IDEA中加入了Kotlin的支持。
2017年Google宣布Kotlin正式成为Android开发一级语言,并且Android Studio也加入了对Kotlin的支持。
2019年Google正式宣布了Kotlin First,未来提供的官方API也将会以Kotlin版本为主
Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,被称之为 Android 世界的Swift,由 JetBrains 设计开发并开源。Kotlin 可以编译成Java字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。
在Google I/O 2017中,Google 宣布 Kotlin 成为 Android 官方开发语言。相较于Java语言,Kotlin 程序文件以 .kt 结尾,如:hello.kt 、app.kt。
语法更加简洁: 大大减少样板代码的数量,使用Kotlin开发的代码量可能会比使用Java开发的减少50%甚至更多。
语法更加高级,相比于Java比较老旧的语法,Kotlin增加了很多现代高级语言的语法特性,使得开发效率大大提升。
语言更加安全: Kotlin几乎杜绝了空指针这个全球崩溃率最高的异常。
和Java是100%兼容的,Kotlin可以直接调用使用Java编写的代码,也可以无缝使用Java第三方的开源库。这使得Kotlin在加入了诸多新特性的同时,还继承了Java的全部财富。
2.Kotlin的工作原理Kotlin可以做到和Java 100%兼容,这主要是得益于Java虚拟机的工作机制。
其实Java虚拟机并不会直接和你编写的Java代码打交道,而是和编译之后生成的class文件打交道。
而Kotlin也有一个自己的编译器,它可以将Kotlin代码也编译成同样规格的class文件。
Java虚拟机不会关心class文件是从Java编译来的,还是从Kotlin编译来的,只要是符合规格的class文件,它都能识别。
也正是这个原因,JetBrains才能以一个第三方公司的身份设计出一门用来开发Android应用程序的编程语言。
二、运行Kotlin代码的三种方式
1.IntelliJ IDEA
此应用对Kotlin支持的非常好,直接创建Kotlin项目就可以独立运行代码!
优点:官方工具,支持性非常好
缺点:需要安装IDE工具
https://play.kotlinlang.org/
在任意Android工程中创建一个Kotlin文件,并编写一个main()函数,即可运行main()函数中的Kotlin代码。
val(value简写):声明一个不可变的变量,
这种变量在初始赋值之后就再也不能重新赋值,对应Java中的final变量。
var(variable简写):声明一个可变的变量,
这种变量在初始赋值之后仍然可以再被重新赋值复制,对应Java中的非final变量。
且每一行代码结尾是不用加分号的
上例中,我们使用val关键字定义变量a并赋值,这里a就会被赋值自动推导成整型变量,而把一个字符串赋值给a的话,那么a就会被自动推导成字符串变量。
1.3 Java与Kotlin数据类型对照表 2.函数函数是运行代码的载体,方法与函数就是同一个概念,都翻译自function,只是不同语言的叫法习惯不同,Java中方法叫法更普遍而Kotlin中函数叫法更普遍一些。
2.1 定义函数的语法规则fun methodName(param1: Int, param2: Int): Int {
return 0
}
fun(function的简写)是定义函数的关键字,无论你定义什么函数,都一定要使用fun来声明。
紧跟在fun后面的是函数名,良好的编程习惯是函数名最好要有一定的意义,能表达这个函数的作用是什么。
函数名后面的一对括号中,可以声明该函数接收什么参数,以参数名称: 参数类型形式书写
括号后面的部分是可选的,用于声明该函数会返回什么类型的数据。如果不需要返回任何数据,这部分可以不写。
两个大括号之间的内容就是函数体了,可以在这里编写函数的具体逻辑。
2.2 单行代码函数的语法糖
当一个函数的函数体中只有一行代码时,可以使用单行代码函数的语法糖:
fun methodName(param1: Int, param2: Int) = 0
使用这种写法,可以直接将唯一的一行代码写在函数定义的尾部,中间用等号连接即可。
return关键字也可以省略,等号足以表达返回值的意思。
Kotlin还拥有出色的类型推导机制,可以自动推导出返回值的类型。
3.逻辑控制
3.1 if条件语句
Kotlin中的if语句相比于Java有一个额外的功能:它是可以有返回值的,返回值就是if语句每一个条件中最后一行代码的返回值。
fun largerNumber(num1: Int, num2: Int): Int {
val value = if (num1 > num2) {
num1
} else {
num2
}
return value
}
仔细观察上述代码,你会发现value其实是一个多余的变量,我们可以直接将if语句返回,这样代码将会变得更加精简,如下所示:
fun largerNumber(num1: Int, num2: Int): Int {
return if (num1 > num2) {
num1
} else {
num2
}
}
当一个函数只有一行代码时,可以省略函数体部分,直接将这一行代码使用等号串连在函数定义的尾部。虽然largerNumber()函数不止只有一行代码,但是它和只有一行代码的作用是相同的,只是return了一下if语句的返回值而已,符合该语法糖的使用条件。那么我们就可以将代码进一步精简:
fun largerNumber(num1: Int, num2: Int) = if (num1 > num2) {
num1
} else {
num2
}
最后,还可以将上述代码再精简一下,直接压缩成一行代码:
fun largerNumber(num1: Int, num2: Int) = if (num1 > num2) num1 else num2
3.2 when条件语句
3.2.1 精确匹配
当需要判断的条件非常多的时候,可以考虑使用when语句来替代if语句(类似Java的switch)。例如获取学生考试分数:
fun getScore(name: String) = if (name == "Tom") {
86
} else if (name == "Jim") {
77
} else if (name == "Jack") {
95
} else if (name == "Lily") {
100
} else {
0
}
fun getScore(name: String) = when (name) {
"Tom" -> 86
"Jim" -> 77
"Jack" -> 95
"Lily" -> 100
else -> 0
}
3.2.2 类型匹配
除了精确匹配之外,when语句还允许进行类型匹配,is关键字就是类型匹配的核心(类似Java中的instanceof)
fun checkNumber(num: Number) {
when (num) {
is Int -> println("number is Int")
is Double -> println("number is Double")
else -> println("number not support")
}
}
1.带参数when
fun getScore(name: String) = when (name) {
"Tom" -> 86
"Jim" -> 77
"Jack" -> 95
"Lily" -> 100
else -> 0
}
2.不带参数when(假设名字以Tom开头的人分数都是86分的场景下)
fun getScore(name: String) = when {
name.startsWith("Tom") -> 86
name == "Jim" -> 77
name == "Jack" -> 95
name == "Lily" -> 100
else -> 0
}
3.3 while循环语句
与Java中while类似
3.4 for-in循环语句 3.4.1 区间闭区间:表示[0,10]范围的区间,且两端是闭区间(…是创建两端闭区间的关键字)
val range = 0..10
fun main() {
for (i in 0..10) {
println(i)
}
}
左闭右开区间:表示[0,10)范围的区间,其中step 2表示区间范围内递增2相当于i = i + 2,且左端是闭区间右端是开区间(until是创建左闭右开区间的关键字)
val range = 0 until 10
fun main() {
for (i in 0 until 10 step 2) {
println(i)
}
}
降序区间:表示[10,1]范围的区间(downTo是创建降序区间的关键字)
fun main() {
for (i in 10 downTo 1) {
println(i)
}
}
for-in循环不仅可以对区间进行遍历,还可用于遍历数组与集合。除此之外,特殊场景无法使用for-in实现的话可以改用while循环去实现。
4.面向对象编程面向对象的语言是可以创建类的,类就是对事务的一种封装,比如说人、汽车、房屋、书等任何事物,我们都可将它封装为一个类,类名通常是名词。而类中又可以拥有自己的字段(表示该类所拥有的属性例如人的姓名年龄、汽车的品牌价格等,字段名通常也为名词)和函数(表示该类可以有哪些行为例如人可以吃饭睡觉、汽车可以驾驶和保养等,函数名通常为动词)
4.1 类与对象可以使用如下代码定义一个类,以及声明它所拥有的字段和函数:
class Person {
var name = ""
var age = 0
fun eat() {
println(name + " is eating. He is " + age + " years old.")
}
}
// main()中进行实例化,且与Java中实例化类似
// 但Kotlin去掉了Java的new关键字
val p = Person()
然后使用如下代码创建对象,并对对象进行 *** 作:
fun main() {
val p = Person()
p.name = "Jack"
p.age = 19
p.eat()
}
面向对象编程基本用法:
1.先将事务封装成为具体的类;
2.将事务所拥有的属性和能力分别定义成类中的字段和函数;
3.对类进行实例化;
4.根据编程需求调用类中字段与方法;
Kotlin中所有非抽象类默认都是不可被继承的,抽象类本身无法创建实例,一定要由子类去继承它才能创建实例,因此抽象类必须可以被继承才行,否则无意义。
4.2.1 继承:open与冒号关键字一个类默认是不可以被继承的,如果想要让一个类可以被继承,需要主动声明open关键字:
open class Person {
…
}
要让另一个类去继承Person类,则需要使用冒号关键字:
class Student : Person() {
var sno = ""
var grade = 0
}
现在Student类中就自动拥有了Person类中的字段和函数,还可以定义自己独有的字段和函数。
注意:Person类后的括号涉及到主构造函数、次构造函数等方面的知识。
主构造函数:
最常用的构造函数
每个类都默认会有一个不带参数的主构造函数,也可以显式指明参数
没有函数体,直接定义在类名的后面即可
例如,我们直接将学号与年级字段放入主构造函数中,则在Student实例化时必须传入构造函数中所要求的所有参数:
class Student(val sno: String, val grade: Int) : Person() {
var sno = ""
var grade = 0
}
// main()
val student = Student("a123", 5)
但是,主构造函数没有函数体,我们想要在其中编写一些逻辑该怎么办?Kotlin提供了init结构体:
class Student(val sno: String, val grade: Int) : Person() {
init {
println("sno is " + sno)
println("grade is " + grade)
}
}
根据子类的构造函数必须调用父类的构造函数这一继承规则,但主构造函数并没有函数体该如何去调用父类构造函数,我们可以在init结构体中类似Java中super.xxx()调用但是不推荐,这时我们就可以在继承时通过其后的括号来指定:
// Student类的主构造函数初始化会调用Person类的无参构造函数,无参数括号也不可省略!
class Student(val sno: String, val grade: Int) : Person() {
init {
println("sno is " + sno)
println("grade is " + grade)
}
}
如果我们改变一下Person类,那么我们的括号后指定的无参构造函数也需要变为有参的构造函数(Person无参构造消失,变为有参构造):
open class Person(val name: String, val age: Int) {
…
}
// Student类
class Student(val sno: String, val grade: Int) : Person(name, age) {
…
}
// Main()
val student = Student("a123", 5,"Jack", 19)
任何类只能有一个主构造函数但可以有多个次构造函数
次构造函数:
也可以用来实例化一个类
有函数体
通过constructor关键字定义
Kotlin规定,当一个类既有主构造函数又有次构造函数时,所有的次构造函数必须调用主构造函数(包括间接调用)例如:
// Student类
class Student(val sno: String, val grade: Int) : Person(name, age) {
constructor(name: String, age: Int) : this("", 0, name, age) {
}
constructor() : this("", 0) {
}
}
4.3 接口
Kotlin中定义接口的关键字和Java中是相同的,都是使用的interface:
interface Study {
fun readBooks()
fun doHomework()
}
而Kotlin中实现接口的关键字变量了冒号,和继承使用的是同样的关键字:
class Student(val name: String, val age: Int) : Study {
override fun readBooks() {
println(name + " is reading.")
}
override fun doHomework() {
println(name + " is doing homework.")
}
}
4.4 数据类
Kotlin中使用data关键字可以定义一个数据类:
data class Cellphone(val brand: String, val price: Double)
Kotlin会根据数据类的主构造函数中的参数将equals()、hashCode()、toString()等固定且无实际逻辑意义的方法自动生成,从而大大简少了开发的工作量。
4.5 单例类Kotlin中使用object关键字可以定义一个单例类:
object Singleton {
fun singletonTest() {
println("singletonTest is called.")
}
}
而调用单例类中的函数比较类似于Java中静态方法的调用方式:
Singleton.singletonTest()
这种写法虽然看上去像是静态方法的调用,但其实Kotlin在背后自动帮我们创建了一个Singleton类的实例,并且保证全局只会存在一个Singleton实例。
5.Lambda编程 5.1 创建集合 5.2 Lambda表达式 5.3 集合的函数式API 5.4 Java函数式API 6.空指针检查 空指针检查 可空类型系统 判空辅助工具 7.Kotlin 中的小魔术 7.1 字符串内嵌表达式 7.2 函数的参数默认值 7.3 字符串内嵌表达式欢迎分享,转载请注明来源:内存溢出
评论列表(0条)