1.程序入口

fun main(args:Array<String>){    println("hello world");}

fun:函数的声明,固定写法

main:程序的入口

args:接受的参数,数据类型字符串

2.变量和输出

  1. 变量的声明

    var name="张三" //变量声明关键词var,语句末尾不需要分号
  2. 数据类型

    类型 范围
    Byte 整数-128~127
    Short 整数-32768~32767
    Int 整数-2147483648~2147483647
    Long 整数-9223372036854775807~9223372036854775806
    Float 小数,小数点可以精确到6位
    Double 小数,小数点可以精确到15-16位
    String 字符串,用双引号引起来的字符串都可以存
    3.类型推断和显示类型声明
    1. 类型推断

      • 在声明一个变量时,我们可以不需要显示声明数据类型,kotlin会根据你为变量赋的值动态地推导出其类型

      • 当一个变量被赋予了某个类型的数值之后,不能再赋给他其他类型的数值,否则,会报类型错误

        fun main(args:Array<String>){    var a=10    //声明变量a , 将int类型的10 赋值给a, a 将只能接受int型数据    a=15    //a="字符串"   //将字符串类型的数据赋值给int型的a ,报错!!    var s="字符串"}
    2. 显示类型声明

      格式:var变量名:变量类型=值

      var a:Int=10 
    3. 变量声明的注意事项

      • 如果声明变量时就赋初值,可以不写类型,此时,类型推导将生效
      • 如果声明变量时没有赋初值,则必须写明类型,否则会报错。格式:var a:Int
    4. 常量的声明

      关键字:val

      格式:val 常量名:常量类型=常量值

3.变量的取值范围

获取某种类型数据的最大最小值

fun main(args:Array<String>){    val minByte:Byte=Byte.MIN_VALUE    val maxByte:Byte=Byte.MAX_VALUE    val a:Int=0b0011    //将二进制的0b0011 转换为10进制,并复制给a }
  • Byte、Int、Long可以通过上述方式获取最大最小值
  • String没有最大最小值,所以没有上述方法

4.Kotlin函数入门

  • main() 程序入口
  • println() 打印

函数声明基本格式:fun 函数名(参数:参数类型){函数体}

5.字符串模板

  • “”,被两个双引号包裹的内容是普通字符串,支持转义符
  • “”" “”",被一对三引号包裹的内容是原样字符串,不支持转义字符,其中的内容被定义成什么样,输出的时候就是什么样
  • 字符串模板格式:${占位字符串}

6.字符串比较

  • 可以使用 == 比较字符串
  • 也可以使用equals(,)方法比较字符串,该方法第二个参数表示是否忽略大小写,true–忽略,false–不忽略
    • equals(,)中第二个参数为true时,效果等价于Java中的equalsIgnoreCase()

7.空值处理

  • 以null表示空值
  • kotlin中定义方法时,默认接收的是非null参数
  • 如果定义某个方法可以接收null参数,则在声明方法参数时在参数后面加上**?**

8.When表达式

类似于Java中的switch,基本使用格式:

when(变量){    分支A -> 表达式    else -> 表达式}

带有返回值的When表达式

var result=when(变量){    分支A -> 表达式(要有返回值,最终将值赋给result)    else -> 表达式(要有返回值,最终将值赋给result)}

9.Loop和Range

  • 声明一个区间数组

    var nums1=1..100  //表示我们声明了一个闭区间数组,其中包含的数值为 1-100。 .. 表示闭区间var nums2=1 util 100 //前闭后开区间,取值 1-99. util 表示前闭后开区间
  • for基本循环格式

    for(变量 in 数组或字符串){    //DO STH }
  • 带有步进的for循环

    for (变量 in 数组 step 步进数量){    //所谓步进,就是递增幅度。默认步进为1    //DO STH }
  • 数组.reversed() //数组内容反转

  • 数组.count() //获取数组的容量,等价于Java中的数组.length

10.List和Map

  1. List

    • List的基本声明格式:

      var list1=listOf(元素1,元素2,元素3)    //声明List时主要是通过 listOf()实现
    • 使用for循环同时遍历索引和索引对应的数值

      for(index,value) in list.withIndex(){    //重点是 withIndex() 方法,index 接收索引,value 接收对应的值    //DO  STH }
  2. Map(词典)

    • 基本声明格式

      var map=TreeMap<键类型,值类型>()map[key]=value
    • 示例代码

      var map=TreeMap<String,String>()    //声明 mapmap["好"]=goodmap["学习"]=study    //添加键值对元素println(map["好"])    //取值并打印

11.函数和函数表达式

  1. 函数的简化

    //原函数:fun sum(a:Int , b:Int):Int{    return a+b}//简化后fun sum(a:Int , b:Int):Int=a+b
  2. 使用var声明函数–函数表达式1

    kotlin 中除了使用基本的 fun 关键字声明函数外,还可以使用 var 声明。示例如下:

    var i={x:Int , y:Int -> x+y} //声明函数i,接收两个Int类型参数 x、y,返回 x+y 的值i(3,5) //调用使用 var 声明的函数 i
  3. 使用var声明函数–函数表达式2

    var j:(Int,Int)->Int={x,y -> x+y}   //声明函数j,它接收的参数是两个Int, 返回一个Int,对应的表达式是 {x,y->x+y}j(4,4)    //调用函数

12.默认参数和具名参数

  • 具有默认参数值的函数声明

    val Pi=3.1415926fun getRoundArea(PI:Float=Pi , radius:Float):Float{    //为变量PI赋予了默认值 Pi,这样,调用该方法时可以不再传递PI。但,如果我们想传入的值和默认值不一致时还是需要传入的    return PI*radius*radius}
  • 调用带有默认参数值的函数

    var a=getRoundArea(3.14f,5.0f) //因为我们相传入的PI和默认值不一致,所以,需要将3.14f传入
  • 具名参数的使用

    所谓具名参数,就是调用某个方法时指明传入的参数是给哪个变量的

    var a=getRoundArea(radius=5.0f) //我们需要的PI值与默认值一致,此时不需要再传入PI值。只需要通过 radius=5.0f 声明我们传入了半径值

13.字符串和数字的转换

var a="13"a.toInt()    //字符串转换为Intvar b=13b.toString()    //Int转换为字符串

14.异常处理–同Java

try{    //可能会出错的代码块}catch(e:Excepiton){    //出错之后的处理逻辑}

15.递归

  1. 利用递归实现阶乘函数

    fun fact(a:Int):Int{    if(a==1){        return 1    }else{        return a*fact(a-1) //函数内调用函数本身就成为了递归    }}
  2. BigInteger

    在上面的方法中,我们用Int来接收阶乘的值,但如果超出了Int的范围,就会返回0.所以这时候就需要用到BitInteger。BitInteger用来表示一个超大值。

    import java.math.BigIntegerfun main(array: Array<String>) {    val num = BigInteger("50")    //声明BigInteger常量时传入一个字符串类型的数值    println(fact(num))}fun fact(num: BigInteger): BigInteger {    return if (num == BigInteger.ONE) {        BigInteger.ONE    } else {        num * fact(num - BigInteger.ONE)    }}

16.尾递归优化

  1. 什么是尾递归

    • 尾递归:是指某个函数的最后一步依旧是调用自身
    • kotlin中尾递归关键字tailrec
  2. 为什么需要尾递归优化

    递归非常耗费内存,因为需要同时保存成千上百个调用记录,很容易发生“栈溢出”错误(stack overflow)。但对于尾递归来说,由于只存在一个调用记录,所以永远不会发生栈溢出错误。

  3. 使用尾递归实现累加

    fun main(args: Array<String>) {    println(accumulation(5, 1))}/** * tailrec 是尾递归函数的关键字 * 尾递归函数是指,在该函数的最后一步操作中依旧是调用函数本身 * 为了实现尾递归,我们定义了该方法接收两个参数:num 是我们传入的需要计算累加值得的变量,total用来接收最终的返回值 */tailrec fun accumulation(num: Int, total: Int): Int {    return if (num == 1) {        total    } else {        accumulation(num - 1, num + total)  //此时,该调用的含义是:先计算 total=num+total,然后计算 num=num-1    }}

17.面向对象入门-定义一个类并构建对象

//定义一个类,包含两个成员变量 height和widthclass Rect(var height:Int,var width:Int)fun main(args: Array<String>) {    var rect=Rect(5,10) //构建Rect对象,不需要new    println("矩形的宽${rect.width}${rect.height}") //引用Rect类中成员变量}

18.静态属性和动态行为/方法-为类定义成员方法

//定义一个类,包含两个成员变量 height和width.并定义一个成员方法class Rect(var height: Int, var width: Int) {    fun getArea(a: Int, b: Int): Int = a * b}fun main(args: Array<String>) {    var rect = Rect(5, 10) //构建Rect对象,不需要new    println("矩形的宽${rect.width}${rect.height}") //引用Rect类中成员变量    println("矩形的面积是${rect.getArea(rect.width, rect.height)}") //引用Rect类中成员变量}

19.面向对象-继承

  • 一个对象直接使用另一个对象的属性或方法-同Java
  • 被继承的父类必须用open修饰,表示允许其他类继承该类
  • 父类中的方法如果允许子类重写,也需要用open修饰
  • 重写父类方法时需要用override修饰重写后的方法
  • 继承的格式:class 子类:父类()

父类:

open class Father {    //用 open 修饰,允许被继承    var character = "性格内向"    open fun action() {    //用open修饰,允许被重写        println("喜欢读书")    }}

子类:

class Son : Father() {    //继承。 Son 继承自 Father    override fun action() {    //重写父类方法        //super.action()        println("儿子的性格是$character")           println("儿子不喜欢看书,但是喜欢唱歌")    }}

20.抽象类及其实现

  • 抽象类的关键字:abstract–同Java
  • 抽象类和方法不需要用open声明可以被继承/实现

抽象类Human:

abstract class Human (var name: String){      //定义抽象类,使用 abstract 修饰。包含成员变量name    abstract fun eat()      //定义抽象方法, 使用 abstract 修饰}

抽象类的子类Man:

class Man(name: String) : Human(name) {    //继承自Human抽象类    override fun eat() {    //必须重写抽象方法        println("${name}是男人,是家中劳力,所以吃的多")    }}

调用子类:

fun main(args: Array<String>) {    var man=Man("张三")    man.eat()}

21.接口及其实现

  • 接口–数据有进有出的交互方式
  • 接口关键字–interface,同Java
  • 接口是事物的能力(代表某种事物的特性),抽象类是事物的本质(代表的是一类事物的共性)
  • 子类实现接口时,接口名后面不需要()

定义接口IMan

interface IMan {    //定义一个男人的接口    fun xiaodidi()}

Man类实现IMan接口

class Man(name: String) : Human(name) ,IMan{  //男人属于人,所以继承Human;男人有小弟弟,所以实现 IMan接口    override fun xiaodidi() {        println("这是重写IMan接口中的方法——男人有小弟弟")    }    override fun pee() {        println("${name}是男人,是站着尿尿的")    }    override fun eat() {        println("${name}是男人,是家中劳力,所以吃的多")    }}

22.代理和委托–大头儿子和小头爸爸的洗碗案例

  • 委托,把自己不干的事情交给别人做
  • 代理,做别人委托的事情
  • kotlin中接口代理关键字:by
  1. 场景说明

    围裙妈妈只负责做饭,不负责洗碗小头爸爸洗一次碗可以赚到10元大头儿子洗一次碗可以赚到1元小头爸爸承揽了洗碗的活,最终交给大头儿子做,中间赚了9元差价
  2. 代码实现–完全委托

    • 定义洗碗的接口

      interface IWashBow {    //定义一个洗碗接口,包含一个洗碗方法    fun washBow()}
    • 大头儿子实现接口

      class BigHeadSon:IWashBow {    //被实现的接口后面不需要加()    override fun washBow() {        println("我是大头儿子,每次洗碗赚1元钱")    }}
    • 小头爸爸实现接口并委托时间给小头儿子

      class SmallHeadFather:IWashBow by BigHeadSon(){     //委托关键字 by;被委托方(即代理方)如果不是单例类,则后面需要跟()}
      fun main(args: Array<String>) {    var father=SmallHeadFather()    father.washBow()    //小头爸爸已经将洗碗的操作委托为小头儿子了,所以,此处本质是调用的小头儿子的洗碗操作}

23.单例模式

  • 单例关键字:object

    我们在定义一个类时,使用object替换class来修饰这个类,就表示这是一个单例类

  • 单例类作为代理人时,不需要()

  1. 场景说明

    小头爸爸为了增进父子感情,想和小头儿子一起洗碗
  2. 代码实现

    • 小头爸爸重写接口方法,未使用单例时的错误写法

      class SmallHeadFather:IWashBow by BigHeadSon(){        override fun washBow() {        println("我是小头爸爸,我把洗碗事件委托给了大头儿子")        BigHeadSon().washBow()  //委托方重写了事件之后,需要手动调用代理方的方法。但是,此处又通过()构建了一个小头儿子对象,已经不再是我们初始委托的那个大头儿子了。所以,此处是有问题的。        println("我是小头爸爸,大头儿子洗完碗之后,我赚了9元")    }}
    • 使用单例后的正确写法

      大头儿子单例类:

      object BigHeadSon:IWashBow {    //单例关键字object,声明为单例类之后会立即在内存中创建单例对象,并一直存在    override fun washBow() {        println("我是大头儿子,每次洗碗赚1元钱")    }}

      小头爸爸委托事件给单例的大头儿子:

      class SmallHeadFather:IWashBow by BigHeadSon{     //被委托方(即代理方)是单例类,不需要通过()构建对象    override fun washBow() {        println("我是小头爸爸,虽然我把洗碗事件委托给了小头儿子,但是我要和他一起洗碗")        BigHeadSon.washBow()  //委托方重写了事件之后,需要手动调用代理方的方法。由于 BigHeadSon是单例的,所以,这还是我们之前委托的那个儿子        println("我是小头爸爸,我和小头儿子洗完碗之后,我赚了9元")    }}
    • 外部调用

      fun main(args: Array<String>) {    var father=SmallHeadFather()    father.washBow()    //小头爸爸已经将洗碗的操作委托为小头儿子了,但因为重写了洗完事件,所以,本子是调用的父亲的洗完事件,父亲的洗完事件中有一部分是自己做的,另一部分是儿子做的}

24.枚举

枚举示例代码:

enum class Week {   //枚举关键字 enum     星期一, 星期二, 星期三, 星期四, 星期五, 星期六, 星期天}fun main(args: Array<String>) {    println(Week.星期一)    println("${Week.星期一}在Week中的索引是${Week.星期一.ordinal}")}

25.印章类/密封类(Sealed Class)

  1. 印章类的特点

    • 子类类型有限的类成为 印章类/密封类
    • 印章类使用 sealed 作为修饰符
    • 印章类本身没有构造方法
  2. 印章类与枚举的区别

    • 都是有限的数据
    • 枚举更注重具体的数据
    • 印章类更注重数据的类型
  3. 示例代码

    • 场景说明

      假设你家有一头公驴、一头母驴、一头公马。那么,它们可能会生出一头小驴,也可能会生出一头小骡子。
    • 代码示例

      在上述场景中,由于他们能生出的儿子类型时固定的,所以,我们可以使用印章类来标识。

      声明印章类

      sealed class Son {  //使用 sealed 声明 Son 为印章类/密封类    class SmallMule() : Son()   //声明小骡子 SmallMule 为 Son的子类。    class SmallDonkey() : Son() //声明小驴子 SmallDonkey 为 Son的子类    fun sayHello(son: Son) {        if (son is SmallMule) {     //判断是不是XX的实例的关键字 is             println("小骡子对大家说大家好")        } else if (son is SmallDonkey) {            println("小驴子对大家说大家好")        }    }}

      调用印章类

      fun main(args: Array<String>) {    var mule = Son.SmallMule()    var donkey = Son.SmallDonkey()    var list = listOf<Son>(mule, donkey)    for (son in list) {        son.sayHello(son)    }}

更多相关文章

  1. Android(安卓)ProGuard使用要点!
  2. Android(安卓)蓝牙对战五子棋项目实现(含人机对战功能)
  3. Android(安卓)recovery 下删除第一次启动后的痕迹
  4. Android(安卓)6.0 开始声明权限的变更
  5. java.lang.NullPointerException: Attempt to invoke virtual me
  6. Android(安卓)防止设备休眠
  7. android 系统搜索框的使用及获取输入
  8. android启动过程详解(二)——解析service
  9. Android(安卓)对集合对象排序(快排与实现接口排序)

随机推荐

  1. Android开发环境的搭建
  2. Android中实现全屏、无标题栏的两种办法(
  3. Android中的Handler机制
  4. Android(安卓)应用架构组件(Architecture
  5. android browser 的几个小feature (一)
  6. android binder机制之--(我是binder)
  7. 视频教程-Android(安卓)Material Design
  8. Android中Context详解
  9. android studio 使用android:drawableTop
  10. Android(安卓)监控程序安装和删除的实现