我的 Kotlin 学习记录

变量:

val : 声明一个不可变的变量,对应java的final变量。

val name:String = "张三"

var: 声明一个可变的变量,对应java的非final变量。

var name:String = "张三"

lateinit : 延迟初始化关键字,不用在声明变量的时候立刻赋值
::object.isInitialized 可用来判断一个变量或对象是否已经初始化

lateinit var name:String  // 不用立刻赋值 也不会报错
name = "张三" //后续使用中进行赋值
if(! ::name.isInitialized){
Log.e("AAA","name 还未初始化")
}

Java 与 Kotlin数据类型对照表

Java基本数据类型 Kotlin对象数据类型 数据类型说明
int Int 整形
long Long 长整形
short Short 短整形
float Float 单精度浮点型
double Double 双精度浮点型
boolean Boolean 布尔型
char Char 字符型
byte Byte 字节型

函数:

a与b是参数," :Int "是返回值类型

fun add(a: Int, b: Int): Int {
        return a + b
    }

条件语句:

  • if 语句: 基本与java一样 ;但是: Kotlin的 if 语句可以有返回值
    例如:
val value = if (a > b) {
        a
    } else {
        b
    }
  • when语句:
    when也有返回值
 val name = "张三"
    val myName = when (name) {
        "张三" -> "欢迎张三" //直接返回值
        "李四" -> { println("李四来了") } //直接代码块运行
        is String -> print("是String类型") //判断类型
        else -> "未定义" //默认返回
    }

循环语句:

  • while循环: 与 java 没有任何区别
  • for循环:
    正序遍历:0到10
 for (i in 0..10) {
        println(i)
    }

倒序遍历:10到0:

  for (i in 10 downTo 0) {
        println(i)
    }

有条件的遍历:
step 2:每次自加2
0 until 10 :不包含最后一个元素

for (i in 0 until 10 step 2) {
        println(i)
    }

类与对象:

  • 创建类
class Person {
    var name = ""
    var age = 0
}
  • 实例化类
val person = Person()
  • 需要继承的类,用 open 声明
open class Person {
    var name = ""
    var age = 0
}

  • 类的继承与实现
class Student : Person(), Eat { //继承自Person,实现了Eat接口
    override fun eat() {
     print("我是学生,我属于人类,我会吃")
    }
}
  • 类得主构造参数
class Student(name: String, age: Int) { //此括号就是主构造函数,init相当于它的函数体
    init {
        print("我相当于主构造函数的函数体")
    }
}
  • 类的次构造函数
// 一个类既有主构造函数 又有 次构造函数 次构造函数必须调用主构造函数(包括间接调用)
class Student(name: String, age: Int) {
    constructor(name: String) : this(name, 12) {
        print("次构造函数")
    }
}

接口:

  • Kotlin 接口允许默认实现
interface Eat { 
    fun eat() { 
        print("我会吃")
    }
}

class Student : Person(), Eat { //继承自Person,实现了Eat接口
    override fun eat() {
        super.eat()
        print("我是学生,我属于人类,我会吃")
    }
}

可见性修饰符:

Java与Kotlin可见性修饰符对照表
修饰符 Java Kotlin
public 所有类可见 所有类可见(默认
private 当前类可见 当前类可见
protected 当前类、子类、同一包路径下的类可见 当前类、子类可见
default 同一包路径下的类可见
internal 同一模块中的类可见

数据类

  • 创建数据类(用 data 关键字声明)
data class DataBean(val name: String, val age: Int) {
    // 没有类体 可以省略大括号
}
  • 数据类的 getter、setter操作
 val dataBean = DataBean("张三", 18)
    // get
    println(dataBean.name + dataBean.age) 
    // set
    dataBean.name = "李四"
    dataBean.age = 20
    println(dataBean.name + dataBean.age)
    
    打印结果:张三18
             李四20

单例类

  • 创建单例类(用 object 关键字声明)
// 在Koltin中我们不需要私有化构造函数,也不需要提供getInstance()静态方法,
//只需要把class关键字改为object,就完成了单例类的创建
object Singleton {
    fun test(mlog: String) {
        println(mlog)
    }
}
  • 调用单例类中的函数(类似java中调用静态方法)
Singleton.test("我是单例类") // 调用了Singleton中的test()函数

密封类(sealed class)

  • sealed class又称为印章类或密封类,用于子类类型有限的类
  • 与when语句配合使用可以自动生成所有子类的条件分支,还不再需要额外添加else分支。

密封类创建(新建kotlin File 使用关键字sealed class来创建):

sealed class TestSealed
class Test1(val msg: String) : TestSealed()  // 继承了密封类 
class Test2(val erroe: String) : TestSealed() // 继承了密封类

与when配合使用的优点:

  • when将不用添加else分支,还能自动生成所有子类的分支
  • 每当添加新的子类时,when都会报错,让你添加新的子类分支,这样减少了程序的出错率
fun getResult(testSealed: TestSealed): String = when (testSealed) { 
    is Test1 -> "t1"
    is Test2 -> "t2"
}

空指针检查

  • 可空类型
var name:String   //不可空变量
var name:String?  //可空变量
  • 可空类型的使用
var bean:Bean?     //可空变量
bean?.getName()    // ?. 操作符:当对象为空时什么都不做,不为空时正常运行
var age = bean?.getAge ?: 18   // ?: 操作符:左边表达式不为空就返回左边结果,否则返回右边结果
bean!!.getId       // !!. 操作符:确定此处不会为空,不再进行空指针检查

字符串内嵌表达式

使用 $ 操作符

    val name: String = "张三"
    println("我是$name,请多关照!")
    val bean = Bean()
    println("我是${bean.getName()},请多关照!")

参数默认值 与 指定传参

fun add(a: Int = 1, b: Int = 1): Int { //参数默认值
    return a + b
}

add(b = 2, a = 2) //指定传参(参数顺序可颠倒)

Kotlin中的 标准函数

  • let 函数
  • 主要作用:配合 ?. 操作符进行判空处理
    var bean:Bean? =null
    // 不用let函数(每次都需要使用?.操作符)
    bean?.getName()
    bean?.getAge()
    
    //注意下面这种方式在bean为全局变量时会报错
    if (bean != null) {
        bean.getAge()
        bean.getName()
    }
    
    // 使用let函数(正常写Lambda)
    bean?.let { b ->
        b.getName()
        b.getAge()
    }
    
    // 使用let函数(当Lambda只有一个参数时,可以省略不写,直接用it代替)
    bean?.let {
        it.getName()
        it.getAge()
    }
  • with函数
  • 大多数用于 一个对象使用多次的场景
 val value = with(bean) {
        // 这里时bean的上下文,可直接调用bean中的方法
        val name = getName()
        val age = getAge()
        name + age.toString() //最后一行作为返回值
    }
  • run函数
  • run 与 with用法一样,只是写法不一样,run需要在某个对象上调用
 val value = bean.run {
        // 这里时bean的上下文,可直接调用bean中的方法
        val name = getName()
        val age = getAge()
        name + age.toString()//最后一行作为返回值
    }
  • apply函数
  • apply无法指定返回值,而是自动返回调用对象本身

实用小例子:

// 跳转界面需要传多个值,使用apply
val intent = Intent(context, SencondActivity::class.java).apply {
        // Intent的上下文,可直接调用Intent中的方法
        putExtra("param1", "data1")
        putExtra("param2", "data2")
    }
    context.startActivity(intent)

定义静态方法

  • 使用单例类来定义静态方法
  • 注意:单例类中的所有方法都只能是静态方法
object Singleton {
    fun test(mlog: String) {
        println(mlog)
    }
}

Singleton.test("哈哈") 
  • 使用companion object(伴生对象)定义静态方法
  • 当我们的类中既要有静态方法,还要有普通方法时,就不能使用单例类了,伴生对象则是更好的选择
class Util {
    companion object { // 写在伴生对象中的方法是静态方法
        fun test() {
            // 我是静态方法
        }
    }

    fun test1() {
        //我是普通方法
    }
}

 Util.test() //调用静态方法
 
 val util = Util()
 util.test1() //调用普通方法
  • 使用@JvmStatic注解,成为真正的静态方法(不常用)
  • @JvmStatic只能加在单例类或者伴生对象中的方法上(加上此注解后,在kotlin与java中都是静态方法,是真正的静态方法)
//单例类
object Singleton {
    @JvmStatic
    fun test() {
       // 我是静态方法
    }
}

//伴生对象
class Util {
    companion object { 
        @JvmStatic
        fun test() {
            // 我是静态方法
        }
    }
}

未完待续。。。

你可能感兴趣的:(Kotlin,加深学习)