Kotlin基础

为什么学习Kotlin?

Kotlin是Google规定的官方Android开发语言
在这里插入图片描述
Kotlin是JetBrains开发的,google把Kotlin作为Android的官方语言。

学习路线

第一种:Android官网:
https://developer.android.google.cn/kotlin/add-kotlin
在这里插入图片描述
第二种:https://www.jetbrains.com/
首页的Learning Tools 选择 Kotlin for Education

文档

Kotlin语言参考文档:
https://www.kotlincn.net/docs/reference/
http://shouce.jb51.net/kotlin/

kotlin基础课目录

Kotlin基础语法 – simple01
Kotlin比较与数组 – simple02
Kotlin条件控制 – simple03
Kotlin循环与标签 – simple04
Kotlin类与对象 – simple05
在这里插入图片描述

kotlin基础

可以选中Kotlin写的类文件,然后点击Tools -> Kotlin -> show Kotlin Bytecode 查看对应的字节码:
在这里插入图片描述
然后点击Decompile可以查看反编译后的java源码:
在这里插入图片描述
通过查看反编译后的java源码可以知道kotlin一些语法的原理。

simple01 Kotlin 基础语法

1.Var 与 Val

可变变量定义:var 关键字
var <标识符> : <类型> = <初始化值>

不可变变量定义:val 关键字,只能赋值一次的变量(有一点点类似Java中final修饰的变量)
val <标识符> : <类型> = <初始化值>

// TODO Var 与 Val
fun main() {

    // 可变变量定义:var 关键字
    // var <标识符> : <类型> = <初始化值>

    // 不可变变量定义:val 关键字,只能赋值一次的变量(有一点点类似Java中final修饰的变量)
    // val <标识符> : <类型> = <初始化值>

    // 可以修改的
    var name: String = "Derry"
    name = "张三"
    name = "李四"

    var info1 = "AAAA" // 类型推导,kotlin可以根据后面变量的值推导出变量的类型,因此不用写 var info1: String = "AAAA"
    var info2 = 'A' // 类型推导  Char
    var info3:Int = 99 // 类型推导  Int

    // 不可以修改的
    val age: Int = 99
    // age = "" 报错


    // 静态语言,即在编译期就决定了info4变量是String类型,再次赋值为Int型的88值就会报错
    var info4 = "LISI"  // info4==String类型
    // info4 = 88   // 但是js可以这么做,因为js是态解释语言
}

class Test {

    // 可以改,可以读  get  set
    //var info1 : String = "A"

    // 只能读, 只有 get
    val info2 : String = "B"


}

2.函数

package simple01.s02

// TODO 函数  方法

// void == :Unit
fun main(): Unit {

    println(add(1, 1))

    lenMethod(1, 2, 3, 4, 5, 6, 7)

    // lambda表达式函数
    val addMethod : (Int, Int) -> Int = {number1, number2 -> number1 + number2}
    val r= addMethod(9, 9)
    println(r)
}

// 返回类型Int
fun add(number1: Int, number2: Int): Int {
    return number1 + number2
}

// 返回类型  == 类型推导 Int
fun add2(number1: Int, number2: Int) = number1 + number2

// 返回类型  == 类型推导 String
fun add3(number1: Int, number2: Int) = "AAA"

// 可变参数 (可变长 参数函数)
fun lenMethod(vararg value: Int) {
    for (i in value) {
        println(i)
    }
}








3.字符串模板

package simple01.s03

// TODO 字符串模板
fun main() {

    // $ 表示一个变量名或者变量值

    // $varName 表示变量值

    // ${varName.fun()} 表示变量的方法返回值

    val name = "张三"

    val age = 28

    val sex = 'M'

    val info = "ABCDEFG"

    println("name:$name,  age:$age,  sex:$sex  info:$info")

    // --- 使用三个换行,则自己不用关心 \n 换行 ,不用自己调整
    val infoMesage = """
        AAAAAAAAAAA
        BBBBBBBBBBB
        CCCCCCCCCCC
        DDDDDDDDDDD
        EEEEEEEEEEE
    """  // 前置空格
    println(infoMesage)

    val infoMesage2 = """
        AAAAAAAAAAA
        BBBBBBBBBBB
        CCCCCCCCCCC
        DDDDDDDDDDD
        EEEEEEEEEEE
    """.trimIndent()  // 没空格
    println(infoMesage2)

    val infoMesage3 = """
        ?AAAAAAAAAAA
        ?BBBBBBBBBBB
        ?CCCCCCCCCCC
        ?DDDDDDDDDDD
        ?EEEEEEEEEEE
    """.trimMargin("?")  // 没空格 控制|
    println(infoMesage3)

    // 需求:显示 $99999.99
    val price = """
        ${'$'}99999.99
    """.trimIndent()
    println(price)
}

4.NULL检查机制

package simple01.s04

// TODO NULL检查机制
fun main() {
    // Kotlin的空安全设计对于声明可为空的参数,在使用时要进行空判断处理,
    // 有两种处理方式,字段后加!!像Java一样抛出空异常,另一种字段后加?

    var info: String? = null

    // println(info?.length)  // 第一种补救:? 如果info是null就不执行 .length,不为null才执行

    // println(info!!.length) // 第2种补救: !! 我自己负责确保info不会为null ==  (不管null或者非null都执行,若info为null则抛出异常)  ==  Java
    // 所以用 !! 的时候要确保info不可能为null

    /*
        if (info != null)           // 第3种补救:  ==  Java
            println(info.length)
    */

    // println(testMethod("AAAAA"))

    // 刚那个提问的呢?
    // ?:  如果你一定要输出null  就让你  “你很牛逼”
    println(info?.length           ?: "你很牛逼")
}

// : Int? 即 允许返回null
fun testMethod(name: String) : Int? {
    if (name == "zs") {
        return 99999
    }
    return null
}

5.区间

package simple01.s05

// TODO 区间
fun main() {

    // 1 到 9
    for (i in 1..9) {
        // println(i)
    }

    // 不会输出
    for (i in 9..1) {
        // println(i)
    }

    // 大 到 小
    for (i in 9 downTo 1) {
        // println(i)
    }

    // 用区间做判断
    val value = 88
    if (value in 1..100) {
        // println("包了 1 到 100")
    }

    // 步长指定
    for (i in 1..20 step 2) {
        // 1 3 5 7 ...
        // println(i)
    }

    // 排除 最后元素
    for (i in 1 until 10) {
        println(i)
    }

}

simple02 比较与数组

1.比较两个值

package simple02.s01

// TODO 比较两个值
fun main() {

    val name1: String = "张三"
    val name2: String = "张三"

    // --- 比较值本身
    // == 等价 Java的equals
    println(name1.equals(name2))
    println(name1 == name2)


    // ---  比较对象地址
    val test1:Int? =  10000
    val test2:Int? =  10000
    println(test1 === test2) // false
}

2.数组

package simple02.s02

// TODO 数组
fun main() {
    // 第一种形式
    val numbers = arrayOf(1, 2, 3, 4, 5, 6, 7, 8)
    // println(numbers[0])
    // println(numbers[7])
    for (number in numbers) {
        // println(number)
    }

    // 第二种形式  value=0
    // 0 + 200 = 200
    // 1 + 200 = 201
    val numbers2 = Array(10,  {value: Int -> (value + 200) })
    for (value in numbers2) {
        println(value)
    }

    // 定义一个变量 value Int类型
    // value=0 + 200
    // {value: Int                ->                     (value + 200) }
}

simple03 条件与控制

1.条件

2.when运用

package simple03

// TODO 条件
fun main() {
    val number1: Int = 9999999
    val number2: Int = 8888888

    // 表达式 比 大小 最大值
    val maxValue = if (number1 > number2) number1 else number2
    // println(maxValue)

    val max: Int = if (number1 > number2) {
        println("number1是最大的哦")
        // TODO
        // ....... 省略 200行代码
        number1
    } else {
        println("number2是最大的哦")
        // TODO
        // .......  省略 200行代码
        number2
    }
    // println(max)

    // 使用区间做判断
    val x = 80
    val y = 29
    if (x in 1..10 && y in 1..50) {
        // println("x y 轴 符合")
    } else {
        // println("x y 轴 不符合")
    }

    println()


    /* val number = 5
     when(number) {
         1 -> println("一")
         2 -> println("二")
         3 -> println("三")
         4 -> println("四")
         5 -> println("五")
         else -> println("其他")
     }*/

    /*val number = 745
    when(number) {
        in 1..100 -> println("1..100")
        in 200..500 -> println("200..500")
        else -> println("其他")
    }*/


    // Object == Any ?
    // val str : String = ""

    val number = 3
    val result = when (number) {
        1 -> {
            println("很开心")
            // 很多很多的逻辑..  省略 200行代码
            // ...
            // TODO ....
            "今天是星期一"
            99
        }
        2 -> {
            println("很开心")
            // 很多很多的逻辑..  省略 200行代码
            // ...
            // TODO ....
            "今天是星期二"
            88
        }
        3 -> {
            println("很开心")
            // 很多很多的逻辑..  省略 200行代码
            // ...
            // TODO ....
            "今天是星期三"
            true
            100
        }
        else -> 99
    }
    // println(result)


    when (8) {
        1, 2, 3, 4, 5, 6, 7 -> println("满足")
        else -> println("不满足")
    }
}

simple04 循环与标签

1.for循环操作

2.自带标签与系统标签

package simple04.s01

// TODO 循环 与 标签
fun main() {

    // TODO  自定义标
    tttt@ for (i in 1..20) {

        for (j in 1..20) {
            println("i:$i, j:$j")

            if (i == 5) {
                // break // j循环给break

                break@tttt // i循环给break,即结束掉外面的循环,类似goto
            }
        }

    }


    // TODO 循环
    var items  = listOf<String>("李四", "张三", "王五")
    for (item in items) {
        println(item)
    }

    //forEach 是一个闭包,默认有一个参数it
    items.forEach {
        println(it)
    }
    //也可以自定义参数
    items.forEach { a ->
        println(a)
    }

    //打印下标,类似迭代器
    for (index in items.indices) {
        println("下标:$index,  对应的值:${items[index]}")
    }

}

// 自带的标签@Derry
class Derry {

    val I = "AAAA"

    fun show() {
        println(I)
        println(this.I)
        println(this@Derry.I)
    }

}

simple05 类与对象

1.父类子类 与 构造函数等

package simple05.s01

// TODO 类与对象
fun main() {

    val person = Person() // 次构造

    val person2 = Person(6465) // 主构造


    Person(464, "Derry") // 次构造
    Person(464, 'M') // 次构造
}
package simple05.s01

// public final class Person 默认就是这样的,不能被继承,可以加open就可以被人家继承了
open class Person(id: Int) // 主构造
{

    // 次构造
    constructor(id: Int, name: String) : this(id) {

    }

    // 次构造
    constructor(id: Int, sex: Char) : this(id) {

    }

    // 次构造
    constructor() : this(787) {

    }

}
package simple05.s01

class Student(id: Int) :
                // Person() // 次构造
                Person(id) // 主构造了
{
    // 在Kotlin中, 全部都是没有默认值的,因此没有赋予初始值会报错
    //var area : String

    // 在Java中, 成员有默认值,但是方法内部没有默认值

    //var name : String? = null // 可以使用String?类型,并赋予初始值null

    // 也可以使用 lateinit 关键字来修饰变量,懒加载,这样就不需要在声明变量的时候赋予初始值了
    // lateinit修饰的变量必须赋值,如果没有赋值就使用,则会报错
    lateinit var name : String
    var age: Int = 0
}

2.接口和抽象类

package simple05.s02

// 默认是 public final class Person ,是不能被人家继承的。
// 如果加上abstract,abstract有open的特征, 相当于open
abstract class Person : Callback , Callback2 {

    abstract fun getLayoutID() : Int

    abstract fun initView()

}
package simple05.s02

class Student : Person() {

    override fun getLayoutID(): Int = 888

    override fun initView() { }

    override fun callbackMethod(): Boolean  = false
}

3.data 与 object

data:

package simple05.s03

/**
 * 数据类  相当于 Java实体Bean
 *
 * 用了data修饰后,就不能加{}了
 */


// 用了data修饰后,会自动生成get方法 set方法 构造方法 equals方法 hashCode方法 toString方法  copy方法
data class User(val id: Int, val name: String, val sex: Char)// 如果User不会再修改,则参数可以使用val

object:

package simple05.s03

// object 只实例一次,相当于 单例。可以看到,类的图标颜色是黄色的
// object修饰后不用加构造函数
object MyEngine {

    fun m() {
        println("M run " + this)
    }

    fun show() {
        println("我就只有一个实例")
    }

}


package simple05.s03

/**
 * 普通的类
 */
class MyEngineNormal() {

    fun m() {
        println("M run " + this)
    }

    fun show() {
        println("show()")
    }

}

测试:

package simple05.s03

// TODO  data数据类 ,object单例
fun main() {

    //data数据类

    val user = User(99, "lisi", 'M')

    val(myID, myName, mySex) = user.copy()//copy()方法的使用
    println("myID:$myID, myName:$myName, mySex:$mySex")

    // _ 代表不接收
    val(_, myName2, _) = user.copy()
    println("myName2:$myName2")



    //object单例

    // --- 调用5此m()方法,相当于new了五次
    MyEngineNormal().m();
    MyEngineNormal().m();
    MyEngineNormal().m();
    MyEngineNormal().m();
    MyEngineNormal().m();


    //而MyEngine只相当于new了1次,因为MyEngine是object修饰的,是单例
    MyEngine.m()
    MyEngine.m()
    MyEngine.m()
    MyEngine.m()
    MyEngine.m()
}

4.自己写单例

package simple05.s04

// TODO Kotlin 单例模式1:饿汉式的单例模式
class NetManager {

    // 用object修饰,只有一个Holder实例
    object Holder {

        val instance = NetManager()

    }

    // 看不到 static,可以用companion(即派生操作)
    companion object {

        // companion里面的方法全部都是 相当于 Java static

        fun getInstance() : NetManager = Holder.instance
    }

    fun show(name: String) {
        println("show:$name");
    }

}

// 客户端
fun main() {
    val net  = NetManager.getInstance()
    net.show("kt Derry1")
}
package simple05.s04

// TODO kt 单例模式2:懒加载的单例模式
class NetManager2 {

    companion object {

        private var instance: NetManager2? = null//kotlin里面全部都没有默认值,必须赋予一个初始值

        // 返回值是NetManager2?:允许你返回null
        fun getInstance(): NetManager2? {
            if (instance == null) {
                instance = NetManager2()
            }

            // 如果是null,也返回去了
            return instance

            // 第二种补救: 我来确保 instance 肯定不为null
            // return instance!!
        }

/*        // 返回值NetManager2?:允许你返回null
        fun getInstance(): NetManager2 {
            if (instance == null) {
                instance = NetManager2()
            }

            // 第二种补救: 我来确保 instance 肯定不为null
            return instance!!
        }*/

    }


    fun show(name: String) {
        println("show:$name");
    }

}

fun main() {
    //如果getInstance()返回值是NetManager2? 即允许返回值是null, 则客户端使用时需要做判断
    val netManager = NetManager2.getInstance()

    // 如果 netManager == null ,则不执行 .show("AAA")
    netManager?.show("AAA")
}

5.内部类与嵌套类

package simple05.s04

/**
 * 内部类和嵌套类的使用
 */
class InnerClass {

    val I = "AAAA"

    // 这个不是一个内部类,所有拿不到外部类的成员
    // 这个是嵌套类,嵌套类的作用:可以在类的里面再写一个类,但是这个类和外部类不交互
    class Sub {

        fun show() {
            println()
        }

        //可以写很多嵌套类
        class A {


            class B {


                class C {

                }

            }

        }

    }

    //inner修饰的这个才是内部类
    inner class Sub2 {

        fun show() {
            println(I)
        }

    }

}

fun main() {

    //嵌套函数
    fun a() {

        fun b() {

            fun c() {

                fun d() {

                }

            }

        }

    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值