kotlin基础笔记

kotlin目前是android第一开发语言

优点:简洁 空值安全 100%兼容java 函数式编程 协程 DSL

开发工具:idea as eclipse

kotlin文件的后缀是: .kt

main函数是程序的入口

基本数据类型:Boolean Byte Char Short int Float Double Long

智能类型判断:自动选择使用java的基本数据类型

kotlin类型类型安全

高精度:BifDecimal

    var big:BigDecimal=BigDecimal(val"0.1212121212112")

var:可变变量
val:不可变量(与java的final修饰的变量类似)

删除空格 : .trim()
删除空格前导 : .trimMargin(marginPrefix:"")

字符串比较: 字符串1 = = = 字符串2(=== 比较字符串引用地址)

元祖数据:
二元元祖 Pair 保存2个数据
三元元祖 Triple 保存3个数据

     val pair:Pair<String,Int>=Pair("ada",20)
     //pair.first  取第一个数据

空值处理:
String : 非空类型
String? : 可空类型

        ?. : 空安全调用符号 ,如果为空不执行后面的代码
        !!. : 非空断言(一定不为空,如果为空,还是会报错)

控制台输入函数 readLine()
控制台输出println()

函数(程序执行的片段):fun修饰
1.无参数,无返回值
2.有参数,无返回值
3.无参数,有返回值
4.有参数,无返回值

字符串模版: $ 站位符

for循环:

                    val s="asdasdasdasd"
                     for(a:Char in s){
                     } 

                   s.forEach(){ 
                    printin(it)
                      }//it是每个元素
      	   //加上index角标的for循环
                for ((index,c) in s.withIndex()) {   
                     println("index=$index c=$c")}

                s.forEachIndexed{ index, c->    }//角标 index 元素 c

break:跳出循环
continue:跳出本次循环
return:结束方法

loop:标签处返回

  		            loop@for(){ //loop可以使任意字符
                                  for(){
                                        if(){
                                             break@loop
                                            }
                                        }
                                }

do while
while

区间:
var r:IntRange=1…100 //1到100
var r=IntRange(1,100)
var r:IntRange=1 until 100 //1到99

           IntRange  LongRange  CharRange(字符区间(a..z))
反向区间    1.val r:IntProgression=10 downTo 1 
           2.val r2:IntProgression=r.reversed() //区间反转  

if:return if (a > b) a - b else b - a

list:

例如: var lists=listOf("121","12312")
        for((i,e) in lists.withIndex()){
            println("$i $e")  //i是索引 e是元素
        }

map:

例如 :var map=TreeMap<String,String>()
      map["hao"] ="good"
      println(map["hao"])

数组:

    例如:var a=arrayof(12,3,4);
            var a= IntArray(10)  //定义元素个数为10个的Int数组
            val intArr = IntArray(10){    0}   //定义了一个长度为10的Int数据类型并且所有元素都为0
        
      数组循环
            for (s in array) {    println(s)}

            array.forEach {    println(it)}

            for循环遍历元素以及角标
            for ((index,s) in array.withIndex()) {    println("角标$index s=$s")}

            array.forEachIndexed { index, s ->    println("角标=$index 元素=$s")}

        修改某一个位置上的元素
                newArr[0] = 20  //将角标0元素值设置为20
                newArr.set(4,20)//将角标4元素值设置为20

        查找第一个元素2
            第一种:  
                arr.indexOf(2)
            第二种:  
                arr.indexOfFirst {it==2 }
        查找最后一个元素2
            第一种: 
                 arr.lastIndexOf(2)
            第二种:arr.indexOfLast {  it == 2  }

When:多分支选择,加强版的switch

基本表达式:when (age) {   
                             7 -> return "开始读小学"    
                            12 -> {        println("开始读中学")         return "开始读小学"    }   
                             else -> return "读社会大学“}
加强版:when(ele){    
                10-> println("它10岁")    is Int-> println("传递的是年龄")    
                in 1..10-> println("在10岁以内")    
                !in 1..10-> println("不在10岁以内")   
                 else-> println("所有情况都不满足")}
   
   表达式不带参数: when{   
                                 ele == 10-> return "它十岁"   
                                 ele is Int-> return "传递的是年龄"   
                                 ele in 1..10->return "在10岁以内"    
                                 ele !in 1..10-> return "不在10岁以内"   
                                 else-> return "所有情况都不满足“}

表达式返回值:val s = when {    
                                        ele == 10 -> "它十岁"    
                                        ele is Int -> "传递的是年龄"    
                                        ele in 1..10 -> "在10岁以内"    
                                        ele !in 1..10 -> "不在10岁以内"   
                                        else -> "所有情况都不满足“}

函数表达式:

                    fun add(a:Int,b:Int):Int{    return a+b}
    函数体只有一行,可以简写
                    fun add(a:Int,b:Int):Int = a+b
    还可以更加简洁
                    fun add(a:Int,b:Int) = a+b

    定义函数变量保存函数引用
                    val addFun1:(Int,Int)->Int = ::add
    执行这个函数
                第一种: addFun1(10,20)
                第二种: addFun1.invoke(10,20)

    定义函数变量时定义函数(这个函数也是求a+b的和)
                    var addFun:(Int,Int)->Int={a,b->a+b }
                执行这个函数
                                第一种:val result = addFun(10, 20)
                                第二种:val result = addFun.invoke(10, 20)

    默认参数:定义函数变量时可以指定默认值
                fun info(name:String = "zhangsan",age:Int){    println("name=$name age=$age")}
    具名参数:调用函数时可以指定参数(没有顺序)
                info(age=age,name = "李四")

可变参数:

        如果接收的参数个数不确定,可以用可变参数表示
                fun add(vararg arr: Int): Int {    
                             var result = 0    
                             arr.forEach {      
                                  result += it    
                              }  
                             return result}

顶层函数:Kotlin里面函数可以独立于class类存在,这就是顶层函数

嵌套函数:函数里面定义函数

            fun main(args: Array<String>) {    
                    var name = "张三"    
                    fun haha(age:Int){      
                          println("名字$name 年纪$age")        
                            return  //只能返回当前函数  不会返回main函数  
                      }   
                     haha(20)    
                     println("呵哈")
              }

异常处理:

    程序抛出异常
                    fun add(a: Int, b: Int): Int {   
                             if (b == 0) {        throw Exception("我是异常")   
                             } else {        return a / b    }}

    Kotlin没有受检异常

    处理异常
                        try {    add(10, 0)
                        } catch (e: Exception) {    println("不能为0")
                        }finally {    println("一定执行的代码")}

递归:直接或间接调用自身的一种方法,只需少量的程序就可描述出解题过程所需要的多次重复计算

       例如:
            递归实现连续数据之和1..100
                    fun allAdd(n: Int): Int {  
                              if (n == 1) {        return 1    
                            } else {        return n + allAdd(n - 1)    }}
            递归实现菲波那切数列1.1.2.3.5.8
                    tailrec fun fib(n: Int): Int {   
                                 if (n == 0) return 0    
                                 if (n == 1) return 1  
                                 if (n > 1) return fib(n - 2) + fib(n - 1)   
                                 return 0}

尾递归:

 函数在调用自己之后没有执行其他任何的操作就是尾递归
    实现尾递归优化
            tailrec fun gsTaAdd(n: Int,result:Int): Int {   
             if (n == 1) {       
             return result+1  
               } else {     
                  return gsTaAdd(n - 1,result+n)   }}

运算符重载:

主构和次构函数:
    主构:class Person(var name:String,var age:Int){}
      次构函数:(次构函数必须要调用主构)
                    class Person(name:String,age:Int){    constructor(name: String,age: Int,phone:String):this(name, age)}
        次构函数间的调用:class Person12(name:String,age:Int){    
                                    constructor(name: String,age: Int,phone:String):this(name, age)    
                                    constructor(name: String,age: Int,phone: String,email:String):this(name, age, phone)}

init:调用主构函数,调用次构函数,都会执行init
    class Person(){//这里如果没有()就代表没有无参构造函数    init { println("执行了init方法")    }      constructor(name:String):this()}

主构 次构 init调用顺序:无论调用主构还是次构都会执行init
                               调用次构先执行init再执行次构中的操作

保存主构中的参数:
    在init方法中保存:class Person(name:String,age:Int){    var name = ""    var age = 0    init {  this.name = name     this.age = age  } }
    变量申明时保存:class Person(name:String, age:Int){    var name = name    var age = age}

主构函数参数的var和val:
参数没有var和val修饰,参数在其他地方不能使用class Person8(name:String,age:Int){}
参数有var修饰,可以使用,可以修改class Person(var name:String,var age:Int){ override fun toString(): String { return “Person(name= n a m e a g e = name age= age)” }} val person = Person8(“张三”,20)person.name = “李四”
参数有val修饰,可以使用,不能修改class Person(val name:String, val age:Int){ override fun toString(): String { return “Person(name= n a m e a g e = name age= age)” }}

次构函数参数使用:次构中参数不能加var或者val修饰
次构参数使用 class Person11(var name: String, var age: Int) { var phone: String = “” constructor(name:String,age:Int,phone:String):this(name,age){ this.phone = phone }}

封装:隐藏内部细节实现,只保留对外接口 通过private
class Restaurant{ //点餐 fun order(){ getTicket() } private fun getTicket(){ println(“取到点餐票了”) }}

类的继承:
普通继承open关键字open class Father{ var name:String = “” var age:Int = 0 open fun sayHello(){ println(“父类hello”) }}class Son:Father(){ }

方法继承和属性继承:方法继承和属性继承也都是通过open关键字
open class Father2{ open var name = “小头爸爸” var age = 30 open fun sayHello(){ println(“hello”) }}class Son2: Father2(){ override var name = “大头儿子” override fun sayHello() { super.sayHello() }}

继承父类主构:
子类主构继承父类主构:
open class Human(val name:String,var age:Int)class Man(name:String,age:Int):Human(name,age)
子类次构继承父类主构:
open class Human(var name:String, var age:Int)class Woman: Human { constructor(name:String,age:Int):super(name,age) constructor(name:String,age:Int,phone:String):super(name,age) constructor(name:String,age:Int,phone:String,email:String):this(name,age,phone)}

抽象类:
抽象类是具体类型的抽象,用abstract表示
abstract class IHuman1(val name:String,val age:Int){ abstract fun eat()}

接口:
接口用interface 表示
interface Ride{ fun rideBike()}

抽象类反映事物的本质,接口代表能力
类只能单继承,接口可以多实现

多态:多态就是同种功能不同的表现形式.
定义抽象类和子类
open abstract class Animal{ abstract fun call()}class Dog: Animal() { override fun call() { println(“汪汪汪”) } }class Cat:Animal(){ override fun call() { println(“喵喵喵”) } }调用 val animal1:Animal = Dog()val animal2:Animal = Cat()

智能类型转换:当判断出类型之后就自动将类型转换成该类型了
open class IAnimal class IDog : IAnimal() { fun wangwang() { println(“狗汪汪叫”) }}val animal1: IAnimal = IDog()if (animal1 is IDog) animal1.wangwang()

嵌套类和内部类:
嵌套类:class OutClass{ var outName = “张三” class InClass{ fun sayHello(){ //println(outName) 无法访问外部类中字段 } }}
内部类inner: class OutClass1{ var outName = “张三” inner class InClass{ fun sayHello(){ println(outName) //可以访问外部类中字段 } }}

内部类中使用this:
可以指定内部this和外部this:
class OutClass2 { var name = “张三” inner class InClass { var name = “李四” fun sayHello() { println([email protected]) } }}

泛型:
泛型就是参数化类型class Box(var value: T)//不知道具体传递的类型

中缀表达式:

    class A {  
      infix fun p(str: String): Unit {
              println(str)    
        }
      }
        A() p "haha"

猜你喜欢

转载自blog.csdn.net/qq_37016139/article/details/84654561