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..10
for (num in nums){
print("$num, ")
}
println()
var nums2 = 1 until 10
for (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 10
for (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.TreeMap
fun main(args: Array<String>){
//创建一个map
var map2 = TreeMap<String, String>()
//赋值
map2["good"] = "好"
map2["bad"] = "坏"
map2["study"] = "学习"
println(map2["bad"])
}
默认参数与具名参数
val PI = 3.14f
fun main(args: Array<String>){
//要写3.14f,3.0f,而不是3.14,3
var 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 = 0
println(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{
//默认参数it
println(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
修饰后,.的操作,可以换成空格的操作