Hello word
前言:上次学习安卓,学了Java开发,简单的搭了几个安卓界面。这次要学习Kotlin语言,然后开发安卓,趁着还年轻,学点新东西,坚持~
未来的你会感谢现在努力的你~
主要学习资料:
- 《第一行代码Android 第三版》
- 菜鸟教程
- android官网-kotlin
- Kotlin 官方文档 中文版
- 2018年黑马安卓开发视频教程
那么,开始吧~
开始-Kotlin语言-安卓开发学习
首先是搭建环境,在一通操作过后,在android studio上成功安装行了kotlin
经典的:hello word
eclipse环境搭建结果:
参数
又是一个绕不开的话题
kotlin中
使用val修饰的变量,是不可变的(value)
使用var修饰的变量,是可变的(variable 可变的)
- tips: 优先使用val来声明一个变量,而当val没有办法满足你的需求时再使用var
函数的格式:
kotlin:
func 函数名(参数名: 参数类型): 返回值类型{函数体
}
oc:
- (返回值类型)函数名(参数类型: 参数名) {函数体
}
只是组合方式不一样
函数的四要素:函数名、参数、返回值类型、函数体
都有
函数的简略写法:
fun sum(a: Int, b: Int): Int{return a+b
}
//如果函数体里面只有一条语句,而且该语句有返回值,则可以去掉{},并省略return,直接使用=:
fun sum2(a: Int, b: Int): Int = a+b
在kotlin中,函数和参数(变量)一样,都是一等公民
那个,也可以将函数表达式赋值给一个变量:
///等号右边,称为:函数表达式var i = {a: Int, b: Int -> a+b}println(i(3, 8))
还有另外一种写法:
//var j:后面,表面是一种类型,j是一个函数类型,两个入参,一个出参//=后面,是一个函数表达式var j:(Int, Int)->Int = {x, y -> x+y }println(j(1, 8))
也就是,函数也可以充当函数里面的参数,或者返回值
for循环
- kotlin也有swift中的开区间、闭区间的概念
四种类型:[],(),[),(]
注意,所谓 “全开区间” 或者是 “左开右闭” 的区间,可以用其他两种方式代替
var nums = 1..10for (num in nums){print("$num, ")}println()var nums2 = 1 until 10for (num in nums2){print("$num, ")}
运行结果:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1, 2, 3, 4, 5, 6, 7, 8, 9,
step n
隔几个,打印1个
for (num in 1..20 step 2){print("$num, ")}
运行结果:1, 3, 5, 7, 9, 11, 13, 15, 17, 19,
reversed()
翻转打印
var nums2 = 1 until 10for (num in nums2.reversed()){print("$num, ")}
运行结果:9, 8, 7, 6, 5, 4, 3, 2, 1,
list和map
使用listOf创建一个list
使用witIndex()获取index的值,然后使用(x, y)两个参数接收
fun main(args: Array<String>){var array = listOf<String>("1", "2", "4", "9")for ((i, e) in array.withIndex()){println("$i "+"$e")}
运行结果:
0 1
1 2
2 4
3 9
//导入TreeMap包
import java.util.TreeMapfun main(args: Array<String>){//创建一个mapvar map2 = TreeMap<String, String>()//赋值map2["good"] = "好"map2["bad"] = "坏"map2["study"] = "学习"println(map2["bad"])
}
默认参数与具名参数
val PI = 3.14ffun main(args: Array<String>){//要写3.14f,3.0f,而不是3.14,3var temp = circleArea(3.14f, 3.0f)var temp2 = circleArea(radius = 3.0f)println(temp)println(temp2)
}//圆的面积
//默认Pi的值是PI
//通过在类型的后面添加 = 符号来设置参数的默认值。
fun circleArea(Pi: Float = PI, radius: Float): Float{return Pi*radius*2
}
readLine()
readLine():获取键盘输入的字,获取后是String?
类型的
异常捕获try-catch
举个🌰:计算器
fun main(args: Array<String>){println("请输入第一个数字:")var a = readLine()while (a == null || a?.count() == 0){println("不能输入空值,请重新输入数字:")a = readLine()}println("请输入第二个数字:")var b = readLine()while (b == null || b?.count()==0){println("不能输入空值,请重新输入数字:")b = readLine()}try {var num1 = a!!.toInt()var num2 = b!!.toInt()var result = sum(num1, num2)println("$num1 + $num2 = $result")}catch (error: java.lang.Exception){println(error)}
}fun sum(a: Int, b: Int):Int{return a+b
}
递归
举个例子:计算n的阶层
5的阶层 = 5 * 4 * 3 * 2 * 1 = 120
fun main(args: Array<String>){println(jieCeng(5))
}fun jieCeng(a: Int):Int{//结束条件if (a == 1) return 1//递归计算return a * jieCeng(a-1)
}
尾递归计算
fun main(args: Array<String>){var result = 0println(add(100, result))
}tailrec fun add(a: Int, result: Int):Int{println("计算机第${a}次计算, result=${result}")//结束条件if (a == 0) return 1//递归计算return add(a-1, result + a)
}
继承
- 如果想继承某个父类,则父类class前需要加
open
,允许被继承 - 如果想重写父类的某个方法,则子类在同名方法前加
overrid
,且父类在方法前加open
,允许被重写
接口和抽象类
- 接口是事物的能力,接口用的时候:接口名即可
- 抽象类是事物的本质,抽象类用的时候:抽象类+()
代理和委托
A委托B去做某事情
B代理A去做某事情
使用by 类名A()
,就可以实现类名A里面的方法
open class Father: IWashBowl by Son(){/**override fun wash() {println("我是爸爸,洗完一次10元")}* */}//或者这样调用
open class Father: IWashBowl by Son(){override fun wash() {println("我是爸爸,我收了妈妈的10元")Son().wash()println("我是爸爸,我不洗碗,但是赚了9元")}
}
单例
创建类的时候,不使用class修饰,而且使用object修饰,则只有一份
印章类sealed
sealed:封闭的、密封的
- sealed class更在意类型
- 枚举更在意数据
//跟enum类似,只有指定有限的类
sealed class Son {//记得加()class XXL(): Son()class XXM(): Son()fun sayHello(){println("hello")}
}fun main(args: Array<String>){//记得加(),才是对象var son1:Son = Son.XXL()var son2:Son = Son.XXM()var son3:Son = Son.XXM()var house = listOf<Son>(son1, son2, son3)for (v in house){if(v is Son.XXM){v.sayHello()}}
}
函数式编程
fun main(args: Array<String>){var names = listOf<String>("tom", "locy", "jack")//forEach函数names.forEach(action = haha)//闭包,匿名函数names.forEach{a -> println(a)}//闭包names.forEach{//默认参数itprintln(it)}
}//函数作为参数,前面使用var 参数名 =
//后面的函数名去掉
var haha = fun (name: String):Unit{println(name)
}
Kotlin高阶函数
一个函数,被用作参数或者返回值,则称为高阶函数
maxBy/minBy
找出数组array,里面age最大的item
array.maxBy{a.age}
找出数组array,里面height最小的item
array.minBy{a.height}
返回的是item对象
var item: Object = array.maxBy{it.age}
filter
- 过滤找到特定条件的对象集合
好几个条件并列执行:
var newArray = array.filter{(it.age>18) and (it.height>168) and (it.age<25)
}
map
- 把原数组某个属性,映射成新的集合
比如:把人群中的名字列出来,放入新的集合中
var newArray = oldArray.map{"${it.name} : ${it.age}"
}
结果:{name1: 18, name2: 30, name3: 19}
any
- 是否有满足某个条件的对象
返回的是一个boolean值
var temp: Boolean = array.any{it.age == 18
}
count
- 统计符合满足条件对象的个数
var count: Int = array.count{it.age<18
}
find
- 查找符合条件的对象,并返回第一个
var item: Object = array.finc{it.address=="北京"
}
groupBy
- 按照特征,把对象分为不同的组
var result: Array = array.groupBy{it.address
}
按照地址,把原来的数组,分别组成新的数组
DSL 领域特定语言
- 扩展函数
- 中缀表达式
函数使用infix
修饰后,.的操作,可以换成空格的操作