安卓开发(2)—— Kotlin语言概述
安卓开发(2)—— Kotlin语言概述
安卓开发(2)—— Kotlin语言
Android的官方文档都优先采用Kotlin语言了,学它来进行Android开发已经是一种大势所趋了。
这里只讲解部分的语法。
这里提供三种方式来运行Kotlin代码:
1 使用IDEA来运行。
2 使用在线IDE来运行:https://play.kotlinlang.org/
3 在Android Studio中运行Kotlin代码:
在项目中的MainActivity同级目录下新建一个kotlin文件就可以直接单独运行。
2.2 变量和函数
2.2.1 变量
在Kotlin中变量先分为可变变量和不可变变量,和别的语言不同,没有那么多复杂的const使用,只有可变变量和不可变变量。可变变量的关键字为var(variable),不可变变量关键字为val(value)。
再由通常的编程语言里面有的类型推导符再分类(相当于就是和给Java/c++等常用的编程语言的变量类型关键字的第一个字符变大写)。
C++ | Java | Kotlin |
---|---|---|
int | int | Int |
long | long | Long |
short | short | Short |
float | float | Float |
double | double | Double |
bool | boolean | Boolean |
char | char | Char |
byte | byte | Byte |
在Kotlin中定义一个变量的最完整格式:var/val 变量名 : 变量类型 = xxx
也可以采用自动推导类型来让Kotlin自动推导变量类型: var/val 变量名 = xxx
//例子
fun main()
{
var a:Int = 10
println("a= " +a)
val b = "hehe"
println(b)
}
2.2.2 函数
Kotlin中的函数关键字是fun(function的简称)。
Kotlin中定义最标准的函数的模板:
fun 函数名(参数名:参数类型,...参数名n:参数类型) : 返回值类型
{
}
其中函数名自己随便选,参数有多少个自己也可以随便定义,如果不想要参数直接写一个空括号,如果函数不需要返回值也可以直接不写返回值类型,还可以利用自动推导类型来确定返回值类型。
//例如
fun test(num1:Int,num2:Int):Int
{
return num1+num2
}
如果函数体只有一行代码,可以直接写在函数体定义的尾部,中间用等号连接(返回值不添加return)。例如:
fun test(num1:Int,num2:Int):Int = num1+num2
再加上Kotlin的自动推导,还可以简化成:
fun test(num1:Int,num2:Int) = num1+num2
2.3 逻辑控制
逻辑控制语句一般有条件语句,循环语句来构成。
kotlin中的条件语句主要有两种方式:if和when。
2.3.1 if条件语句
大体上和C++/Java等编程语言的if-else流程语句一样,但是Kotlin的if-else语句和C++/Java的代码不同的是,if-else语句有返回值。
var num1 = 10
var num2 = 20
var TestNum = if(num1>num2) {
num1
}else{
num2
}
println(TestNum)
2.3.2 when条件语句
Kotlin中的when条件语句有点类似与C++/JAVA中的switch语句,但是when语句中抛弃了switch语句中的break,直接作为一次性跳转使用,不会因为没有break就继续向下执行。
格式:
when(匹配项)
{
匹配值 -> {代码逻辑} //如果只有一行代码,可以不用加{}
}
//例如:
fun main()
{
var age = 1
when(age)
{
1 -> println("一岁")
2 ->{
println("只有两岁")
}
else -> println("Error")
}
}
除了精致匹配匹配项里的内容外,还可以进行类型匹配:
fun CheckType(num: Number)
{
when(num)
{
is Int -> println("输入的是Int类型")
is Double -> println("输入的是Double类型")
else -> println("输入的不是Int或者Double类型")
}
}
//这里的Number类型是Kotlin内置的一个抽象类,Kotlin的变量类型都是Number类型的子类,所以可以用它来使用子类,这个相当于
//C++里面的多态了。
//is是一个关键字用来判断变量的类型,相当于java里面的instanceof
2.3.3 循环语句
kotlin主要提供了while和for循环两种循环语句。
while循环语句和C++/JAVA/C等语句都一样,但是在for循环语句中有很大的改变。
for循环中最主要的是for-in的用法。
在用kotlin中的for-in循环时,首先得明白kotlin中的区间的概念,其实就是一个范围。
可以使用kotlin代码来让某个变量作为一个区间,如:
var test = 0..10
这段代码的意思是定义了一个从0到10的左闭右闭区间,默认是
中间每个相差1,其中 “..”是创建两端闭区间的关键字,在”..”的两边指定区间的左右端点就可以创建一个左闭右闭区间了。
在创建了区间后,就可以使用for-in循环来遍历这个区间了,例如:
fun TestCircle()
{
val a = 0..10
for(i in a){
println(i);
}
}
还可以创建左闭右开的区间,因为通常在数组中都是从0开始,比如char[10]的范围就是0-9的闭区间。
//创建左闭右开区间
var a = 0 until 10
//得到的是一个[0,10)
如果想在循环中跳过一些元素,可以使用step关键字:
fun TestCircle2()
{
for(i in 0 until 10 step 2)
{
println(i)
}
}
//表示每次自增2
前面创建的都是从小到大的区间,那么肯定有要用到从大到小的时候。如果想要创建一个从大到小的就需要添加downTo关键字,例如:
fun TestCircle3()
{
for(i in 10 downTo 1) //这里就是创建了一个[10,1]的区间,同样也可以采用step来跳过一些
{
println(i)
}
}
2.4 Kotlin面向对象编程
Kotlin同样也是一门可以面向对象的语言。
新建类有两种办法,一种是直接利用Android Studio IDE来创建,还有一种是直接源代码创建。
利用IDE创建:
右键想要在那个包里面创建->New->Kotlin File/Class:
使用类的关键字class直接定义就好了,类的属性可以在函数体里展示,也可以在类的内部展示
//例
class Test(var num1:Int,var num2:Int)
{
var num3 = (num1+num2)*2
}
//这就写好了一个很简单的类
实例化类,用类来创建对象,就等于把类当作一个变量类型来使用就好了,就像Int,Double一样。
//实例化:
var TestClass = Test(1,2)//这样就是实例化了一个Test类的对象
//使用类和对象的实例:
class a
{
var name = "test"
}
fun TestClass()
{
var Test = a()
println(Test.name)
}
2.4.2 继承和构造函数
在Kotlin中的继承和别的面向对象语句继承不一样。
Kotlin里面的类默认是不可继承的(抽象类除外),如果想要类可以被继承,需要在创建的时候添加OPEN关键字,例如:
open class Person
{
...
}
//加上了open关键字后,这个类就可以被继承了。
继承首先得需要了解Kotlin里面的构造函数,每个Kotlin中的类有一个默认的构造函数和C++一样,这个构造函数不需要写,只需要在实例化的时候将创建类的时候申明的成员也加上去,但是在类的主体中的成员就不需要添加了。
相当于这个默认的主构造函数就是根据申明时的成员将其赋值给类创建的对象。
//例:
class TestClass(var num1:Int,var num2:Int)
{
var num3 = num1 + num2;
fun TestClassPrint()
{
println(num1)
println(num2)
println(num3)
}
}
fun TestClassFun()
{
var Test= TestClass(1,2)
Test.TestClassPrint()
}
继承:在继承时首先需要要继承的该类申明时有OPEN关键字,然后直接在定义的子类的时候加上: 和父类的构造函数就好了,和C++一样的。
class Person()
{
}
class Person2 : Person()
{
}
2.4.3 接口
这个就和JAVA中的接口差不多了,同样也和C++里面的虚基类类似。
首先创建一个接口类:
interface study
{
fun ReadBooks()
fun DoHomeWork()
}
接下来就可以用子类来重写实现了:
class Student : Study
{
override fun ReadBooks()
{
println("学生正在看书")
}
override fun DoHomeWork()
{
println("学生正在做作业")
}
}
//重写接口类的函数需要添加override关键字
还可以在接口类中写默认函数,也就是将一个函数实现,那么接下来继承接口类的类可以选中不实现该函数,但是没有实现的接口类函数就必须要实现。
//例如:
interface study
{
fun ReadBooks()
{
println("看书中")
}
fun DoHomeWork()
}
2.4.4 成员属性
每门面向对象语言都会有成员属性修饰符,Kotlin也不例外,Kotlin有public,private,protected和internal四种。
属性 | 作用 |
---|---|
public | Kotlin中默认是public,public表示对所有都可见 |
private | 只有当前类可见 |
protected | 对当前类,子类和包路径下的类看邮件 |
internal | 同一模块中的类可见 |
2.4.5 数据类和单例类
数据类,在创建后,会自动生成很多和数据相关的函数,比如计算hash值的hashcode,比如判断是否相等,例如:
data class CellPhone(var brand:String,var price:Double)
fun TestBase()
{
var test1 = CellPhone("test1",1.11)
var test2 = CellPhone("test2",2.22)
println("CellPhone1 等于 CellPhone2 是真的吗?" + (test1 == test2))
}
单例类:单例类只能创建一个对象,借此来避免创建多个对象。
在别的C++/JAVA等语言或许会比较麻烦,但是Kotlin非常的遍历,只需要在创建类前添加关键字object就好了,例:
object SingClassTest()
{
fun Test()
{
println("test")
}
}
2.5 Lambda编程
Lambda的定义是:一小段可以作为参数传递的代码。(类似与C里面的宏定义)
//语法结构
{参数名1:参数类型,参数名2:参数类型 -> 函数体}
//函数体可以写任意多少行代码
//最后一行代码会作为返回值
2.5.1 集合的创建与使用
类似于C++的STL一样,就好比是Kotlin内置的一些类。类似于C++的STL一样,就好比是Kotlin内置的一些类。
//在java中
val list = ArrayList<String>()
list.add("test")
//c++
vector<int> a;
a.push_bak(1);
//Kotlin提供内置的listOf()函数来初始化集合
val list = listOf("test1","test2")
//for-in语句不仅仅可以用在循环,还可以用在集合这里。
但是需要注意的是listOf创建的集合是不可变的,只能读取,不能修改删除,添加等操作。
创建可变的集合:使用mutableListOf()函数来创建就好了。就可以使用add()等等操作了。
fun TestLamba()
{
val list = mutableListOf("Apple","Banana","Potato")
list.add("hehe")
for(i in list)
{
println(i)
}
}
前面写的是list列表集合,set无序集合和list列表集合使用办法一样。
还有Map键值对集合,Map是一种数据结构的内容。
//使用办法
val map = HashMap<String,Int>()
map.put("apple",1)
map.put("banana",2)
map.put("orange",3)
//可以用put()和get()方法来添加和获取
//还可以直接使用类似于数组下标操作来处理
var test = map["apple"]
map["apple"] = 1000
同样map也有初始化函数mapOf()和mutableMapOf()来简化map的初始化。
2.5.2 集合的函数API
相当于各种内置的Lambda的类里面有公用的API函数来使用,和STL是一样一样的。
例如:
//在一个水果集合里面找到单词最长的那个
var list = listOf("apple","banana","pear","Watermelon")
val maxLengthFruit = list.maxBy{it.length}
//这个一个由lambda表达式简化过来的版本
//接下来由繁入简来讲述这个API
看最原始的版本:
var list = listOf("apple","banana","pear","Watermelon")
val lambda = {fruit:String -> fruit.length}
val maxLengthFruit = list.maxBy({lambda})
//maxBy这个函数根据传入的参数来确定遍历集合的方式
优化1:不需要单独的lambda变量
var list = listOf("apple","banana","pear","Watermelon")
val maxLengthFruit = list.maxBy{fruit:String -> fruit.length}
优化2:在Kotlin中,当Lambda参数是函数的最后一个参数时,可以把lambda表达式单独用{}独立出来:
var list = listOf("apple","banana","pear","Watermelon")
val maxLengthFruit = list.maxBy(){fruit:String -> fruit.length}
优化3:如果Lambda参数是函数的唯一一个参数,还可以将函数外的括号省略
var list = listOf("apple","banana","pear","Watermelon")
val maxLengthFruit = list.maxBy{fruit:String -> fruit.length}
优化4:当lambda表达式的参数列表只有一个参数时,也不必声明参数,可以直接用it关键字代替(也就是代替它传进来的)
var list = listOf("apple","banana","pear","Watermelon")
val maxLengthFruit = list.maxBy{it.length}