第二章 探究新语言,快速入门Kotlin编程
2.3 变量和函数
2.3.1变量
val a = 10 // 声明不可变变量
var b=10 // 声明可变变量
val a: Int = 10 // 声明变量类型
2.3.2 函数
fun largerNumber(num1: Int,num2 :Int):Int{
return max(num1,num2)
}
//下面是只有一行代码时的简化
fun largerNumber2(num1:Int,num2:Int) = max(num1,num2)
2.4 程序的逻辑控制
2.4.1 if条件语句
fun largerNumber3(num1:Int,num2:Int):Int{
var value = 0
if(num1>num2)
value = num1
else
value = num2
return value
}
与常规见的if不同,这个if可以用有返回值,这样写:
fun largerNumber4(num1:Int,num2:Int):Int{
var value = if(num1>num2){
num1
}
else
{
num2
}
return value
}
再使用语法糖的条件:
fun largerNumber5(num1:Int,num2:Int) = if(num1>num2){num1}else{num2}
2.4.2 when条件语句
类似switch
可以进行精确匹配:
fun getScore(nume:String)=when(name){
"Tom"->86
"Jim"->77
"Lily"->100
else ->0
}
也可以进行类型匹配:
fun checkNumber(num:Number){
when(num){
is Int->println("number is int")
is Double->println("number is Double")
else ->println("number not support")
}
}
when还有一种不带参数的用法:
fun getScore2(nume:String)=when{
name.startsWith("Tom")->86
name=="Jim"->77
name=="Lily"->100
else ->0
}
注意与getScore进行比较,查看这种方法可以实现的功能。
2.4.3 for循环
for-in语句:注意0…10相当于val range=0..10
是个闭区间的
for(i in 0..10){
println(i)
}
但是一般我们希望的是左闭右开val range =0 until 10
,并且或许有步长的要求:
for(i in 0 until 10 step 2){
println(i)
}
前面都是升序的,如果想降序:
for(i in 10 downTo 1){
println(i)
}
2.5 面向对象编程
2.5.1 类与对象
创建一个类:
class Person {
var name=""
var age = 0
fun eat(){
println(name + "is eating. He is "+age+"years old.")
}
}
函数中创建对象并调用他的成员函数:
val p = Person()
p.name="fan"
p.age=20
p.eat()
2.5.2 继承与构造函数
首先给Person加上open的关键字
open class Person(val name:String,val age:Int){
fun eat(){
println(name + "is eating. He is "+age+"years old.")
}
}
然后是Student类继承:
class Student(val sno:String,val grade:Int, name:String, age:Int):Person(name,age) {
init{
println("sno is "+sno)
println("grade is " + grade)
}
constructor(name:String,age:Int):this("",0,name,age){}
constructor():this("",0)
}
上面的Student类中的constructor是此构造函数,他必须调用主构造函数。
函数中调用(注意student有三种调用方法:
val s = Student("a123",5,"Jack",20)
val s2 = Student()
val s3 = Student("jack",10)
s.eat()
2.5.3 接口
首先定义接口
package com.example.myapplication1
interface Study {
fun readBooks()
fun doHomework(){
println("do homework default implementation.")
}
}
然后重载函数:
class Student(val sno:String,val grade:Int, name:String, age:Int):Person(name,age),Study {
init{
println("sno is "+sno)
println("grade is " + grade)
}
constructor(name:String,age:Int):this("",0,name,age){}
constructor():this("",0)
override fun readBooks() {
println(name + "is reading")
}
override fun doHomework() {
println(name + "is doing homework")
}
}
最后在主函数中调用
fun doStudy(study:Study){
study.readBooks()
study.doHomework()
}
//主函数中:doStudy(s)
doStudy运用了多态的性质
2.5.4 数据类与单例类
data class CellPhone(val brand:String,val price:Double) {
}
object Singleton{
}
当使用data关键字,将自动把equals()、hashCode()、toString()等固定没有意义的方法自动生成。第二个object类用来创建一个单例类。
2.6 Lambda编程
2.6.1 集合的创建与遍历
经典的老朋友list、set、map
fun main(){
println("hello kotlin!")
val list = listOf("A","b","c") // 不可变集合,只能读
for(each in list){
println(each)
}
val list2 = mutableListOf<String>("a","b","c","d")
list2.add("water")
for(each in list2)
println(each)
val set = setOf("A","b","c")
val set2 = mutableSetOf<String>("A","b","c")
val map = HashMap<String,Int>()
map.put("Apple",1)
map.put("Banana",2)
map["Pear"]=4
val number = map["pear"]
//还可以下面的方法直接初始化
val map2 = mapOf("Apple" to 1,"Banana" to 2,"Orange" to 3,"Pear" to 4)
for((key,value) in map){
println("key is "+key+"value is "+value)
}
}
2.6.2 集合的函数式API
val list3 = listOf("Abbb","ba","c") // 不可变集合,只能读
val maxLengthWord = list3.maxBy({fruit:String ->fruit.length})
val maxLengthWord2 = list3.maxBy{fruit:String->fruit.length}
val maxLengthWord3 = list3.maxBy{it.length}
val anyResult = list3.any{it.length<2}
val allResult = list3.all{it.length<2}
val newlist = list3.filter{it.length<3}.map{it.toUpperCase()}
2.6.3 Java函数式API的使用
嘿嘿,其实这里我没看懂现在,懒得滤
Thread{
println("Thread is runnig")
}.start()
2.7 空指针检查
在调用参数的方法前先进行一个判空的处理:
如果是java的代码:
public void doStudy(Study study){
if(study!=null) {
study.readBooks()
study.doHomework()
}
}
2.7.1 可空类型系统
kotlin则下面这个代码没空指针风险。
fun doStudy(study:Study){
study.readBooks()
study.doHomework()
}
这个时候Kotlin将空指针一场的检查提前到了编译时期,也可以用问号,来让可以传入空:
fun doStudy(study:Study?){
if(study!=null) {
study.readBooks()
study.doHomework()
}
}
2.7.2 判空辅助工具
?.
if(a !=null)
a.doSomething()
等价于
a?.doSomething()
?:
val c = a?:b
非空断言工具
a!!.doSomething()
编译器不做空指针检查了,若出问题,就抛出空指针异常。
let函数
与?.进行配合可以方便检查空指针
fun doStudy(study:Study?){
study?.readBooks()
study?.doHomework()
}
2.8 Kotlin 中的小魔术
略