Kotlin实战感悟(换地方拧螺丝了)

本文详细介绍了Kotlin的修饰符,如可见性、vararg、var与val的区别,以及out关键字、枚举和控制语句。还讨论了对象、类型检查、字符串操作、集合与函数的使用,包括lambda表达式、高阶函数、扩展函数和Android中的应用。此外,还涉及了异常处理、运算符重载等高级话题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

kotlin

修饰符

可见性修饰符

类成员顶层声明
public默认可见性所有地方可见所有地方可见
private类中可见文件中可见
protected子类中可见
internal模块中可见模块中可见

子类可重写的条件

  • 父类中被open的方法
  • 子类继承了抽象类,抽象方法必须被重写
  • 子类继承的父类里的override方法

vararg 用来表示多个参数,类似于java中…

fun test(vararg tags: String) {
    println(tags[0])
    var list = listOf(*tags)
    println(list)
}

var 与val的区别

区别
varprivate
valprivate final

out 关键字

枚举

enum class TimeTypeEnum(val value: String) {
    LATESTWEEK("1"),
    LATESTMONTH("2"),
    LATESTYEAR("3")
}

until [0 x)

        for(key in 0 until normal_praise){
            LogUtil.d("=====key===${key}")
        }

Any

    var flag:Any="ddd"
     Object flag = "ddd";
  • Any是所有类型的超类型,是所有类型的根,包括基本数据类型

const 的作用

默认java调用kt的静态属性是需要调用getXX()的

     Cat.Companion.getAge()   //访问Cat.kt 文件的age属性

用 const 修饰后 相当于以 public staic final 的属性直接暴露给java

      Cat.age

? 表示该引用可以为null

!! 非空,如果标记的变量是null会直接报错

    val  str:String?=null
    println(str.toString()) //打印null
    println(str!!.toString()) //会报错,此时断言str不为null

as

final

open 关键字

  • 用来修饰父类以及父类中需要被重写的方法甚至是属性
  • java中的类和方法默认都是open,但kt里都是final
  • 子类中重写的方法可以显示的用final标注,从而使继承该子类的类不再重写该方法
  • 抽象类中抽象方法和抽象属性都是默认open的,而实现的方法和属性都是final,要想重写必须手动添加open

object

  • 接口中可以写方法的实现
  • 单继承,多接口实现
interface CallBack {
    fun callBack(str: String)
    fun getTest(){
        println("调用了接口里的方法")
    }
}

abstract

companion object

  • 需要在类中定义静态方法或者静态变量 (也就是android中的工具类或者一些常量)
class Cat {
    companion object {
        var name:String="hcy"
        fun  getName(){
            println(name)
        }
    }
}

object 修饰的类

  • 静态类
  • 单例
  • 方法和变量都是静态的
object Dog {
    var name:String?=null
    val age:Int=10
    fun  play(){
        println("playing!!!!")
    }
}
public final class Dog {
   @Nullable
   private static String name;
   private static final int age = 10;
   public static final Dog INSTANCE;

   @Nullable
   public final String getName() {
      return name;
   }

   public final void setName(@Nullable String var1) {
      name = var1;
   }

   public final int getAge() {
      return age;
   }

   public final void play() {
      String var1 = "playing!!!!";
      boolean var2 = false;
      System.out.println(var1);
   }

   private Dog() {
   }

   static {
      Dog var0 = new Dog();
      INSTANCE = var0;
      age = 10;
   }
}

is 类型的检查和转换

  • 一旦被检查过的类型,不需要额外的转换就能直接引用属于这个类型的成员
v is String
v instanceof String

字符串

原始字符串

//原始字符串
fun  func1(){
    var str1="hcy\n"
    val str="""hcy\n"""
    for (c in str){
        println(str.length)
    }
}
  • 原始字符串用三个引号,内部没有转义

遍历字符串的写法

for in

fun  strTest(str:String):Unit{
    for (c in str){
        println(c)
    }
}

控制语句

if

fun funcIf(a: Int, b: Int) {
    var max = if (a < b) {
        a
    } else {
        b
    }
    println("max==${max}")

}

when

  • switch
  • 代码块中的最后一句是返回值
fun  funcWhen(tag:Any):Unit{
    when(tag){
        1-> println("AAAA")
        2-> println("BBBB")
        3-> println("CCCC")
        4,5->{
            println("DDDD=or=EEEE")
        }
        in 6..8->{
            println("在[6,8]区间里")
        }
        is Int->{

        }
        else -> println("其他")
    }
}

kt 三目表达式的写法

kt 不支持三目表达式

集合

list

forEach

    var arr=Array(5){i->i}

    arr.forEach {
        println(it)//0,1,2,3,4
    }

数组的创建

   var arr=Array(5){i->i}

基本数据类型的数组(未装箱的数组)

var a= IntArray(5)
  • 创建了一个基本数据类型的数组,长度为5,每个默认值为0

基本类型装箱后的数组转为基本数据类型的数组

toIntArray()

遍历数组下标索引

fun  funcFor2():Unit{
    var arr= arrayOf("AAA","BBB",333,444,555);
    for (index in arr.indices){
        println("index==${index},value==${arr[index]}")
    }
}

遍历数组的下标和值

 a.forEachIndexed { index, value ->
        println("基本数据类型的数组$index===$value")
    }

遍历list的下标和值

fun  funcFor():Unit{
    var arr= arrayOf("A",2,3)
    for ((i,v)in arr.withIndex()){
        if (v is String){
            println("String类型:index==${i},value==${v}")
        }else{
            println("index==${i},value==${v}")
        }

    }
}

map

遍历map的key value

        for ((key,value) in params){
            Log.d("主app参数::","key==${key},value==${value}")
        }

集合的过滤

filter

   val filterList =
            data.filter { !(it.class_guid.equals(currentClass?.class_guid) && it.class_name.equals(currentClass?.class_name)) }

downTo step

10分钟倒计时

    var total = 10 * 60 * 1000
    for (i in total downTo 0 step 1000) {
        Thread.sleep(1000)
        println(i/1000)
    }

异常

  • 不区分受检异常和未受检异常,不用指定函数抛出的异常,可以处理或者不处理异常

函数

重写属性的set方法 field 关键字

  var age: Int = 0
        set(value) {
            println("${name}age setter")
            field = value
        }

修改访问器的可见属性

外部 只能get不能set

    var address: String = ""
        private set

委托 by 关键字(像是装饰者模式代码简化版)

  • 一个旧接口
interface Person {
    var name: String
    var age: Int
}
  • 一个需要被扩展的类(这个类实现了旧接口)
class OldStu(override var name: String, override var age: Int) : Person {

}
  • 一个扩展的新类
class Student(var per: OldStu, var sex: String) : Person by per {

    fun getInfo() {
        println("${per.age}==${per.name}===$sex")
    }
}

扩展函数

  • 类的扩展函数是不能访问类的private 和 protected 成员
  • 类的成员函数,要定义在类的外面
  • 可以直接被扩展的类的其他方法和属性,但不能访问私有的或者是受保护的成员

Android&&Kotlin

启动activity

        startActivity(Intent(MainActivity@this,LoginActivity::class.java))

点击事件的写法

        tv_refresh?.setOnClickListener {
            present.getStudentContacts(
                SPUtils.getInstance().getString(TeacherConstants.YID),
                currentClassGuid,
                "",
                getThisActivity()
            )
        }

kotlin 接口回调的写法

声明带返回值的方法不一定都要返回值类型

=

    fun getTest(num:Int)=when(num){
        1->{
            "1"
        }
        else->{
            "ddd"
        }
    }

伴生对象

是声明在类中的普通对象

  • 代替了java中的静态方法和静态变量
  • 可以实现接口,并且可以受用扩展函数和属性y

lambda 使用

调用对象的属性

对象::属性

函数式编程

            var position = 0
            val result = it.map { poi: PoiInfo ->
                MyPoi(poi, position++ == 0)
            }.sortedBy { myPoi: MyPoi ->
                //按照poi的坐标到定位的坐标的距离做升序排序
                BdMapUtils.getDistance(
                    myPoi.poi!!.location, LatLng(
                        current!!.latitude,
                        current!!.longitude
                    )
                )
            }

惰性求值 :序列

  • 惰性求值会比及早求值性能高
  • 惰性求值是逐个的,及早求值可能是批量的
序列的操作
  • 中间操作 返回另一个序列
  • 末端操作 返回的是结果 末端操作执行了所有延期的计算

函数式接口

只有一个抽象方法的接口

?. 安全调用符

不为null会往下执行,为null调用就不发生

?: 空合并运算符

isNullOrBlank isNullOrEmpty 区别

  • isNullOrBlank 判断null,"","\r" 如果字符串里有转义字符,会判断
  • isNullOrEmpty 判断null,""

泛型默认是可空的 Any?

fun <T> fun5(a: T) {
    
}

指定泛型不为null

fun <T:Any> fun5(a: T) {
    
}

kt不区分基本数据类型和引用类型

Unit Void Nothing

Nothing没有任何的值,这个函数永不返回,通常用来抛出异常
Unit具备java中void的功能,可以作为参数类型

kt中集合是允许存放null的

只读集合

  • 只读集合不一定是不可变的
  • 只读集合并不总是线程安全的
  • set,map,list 都是只读 实现的是connection接口

可变集合

  • hashset hashmap arraylist 是可变的,也就是可添加的,实现的是mutableconnection

平台类型

java 中的类型在kt中被解释成平台类型,可以把它当做null或者非null对待

运算符重载

operator

表示将函数作为相应的约定的实现

重载二元算术运算符

a+b plus

data class OldStu(var name: String, var age: Int) : Person {
   operator fun plus(otherage: OldStu): Int {
       return age + otherage.age
   }

}
fun fun9() {
   println(OldStu("hcy", 22) + OldStu("hcy1", 33))
}

plusAssgin 暂时没搞懂,貌似是可变集合定义的

重载一元运算符

+a unaryPlus

data class OldStu(var name: String, var age: Int) : Person {
    operator fun plus(otherage: OldStu): Int {
        return age + otherage.age
    }


    operator fun unaryPlus():Int{
        return age +1
    }

}

    println(+OldStu("hcy,", 22))

自定义下标运算符 get set

data class OldStu(var name: String, var age: Int) : Person {
    operator fun plus(otherage: OldStu): Int {
        return age + otherage.age
    }


    operator fun unaryPlus(): Int {
        return age + 1
    }

    operator fun get(index: Int): String {
        return when (index) {
            0 -> {
                name

            }
            1 -> {
                "$age"
            }
            else -> {
                throw Exception()
            }
        }
    }
}

fun fun12() {
    var stu=OldStu("hcy",21)
    println(stu[0])
    println(stu[1])
}
[index]get/set
containsin
1…10rangeTo
for(in)iterator

解构声明

组件函数

  • data class 自带组建函数,不需要自己定义组件函数
  • 组件函数的定义 operator fun component1()=name,函数名必须是component+数字

委托属性

高阶函数

  • 以另一个函数作为参数或者返回值的函数

函数类型

声明函数类型

(参数类型)->返回类型

  • 返回类型可空
fun fun14(a: Int, b: Int): (Int, Int) -> Int {
    val sum: (Int, Int) -> Int = { x, y -> x + y }
    //声明可null的函数类型
    var test: ((String?, String?) -> String)? =
        { x, y -> "$x+$y" }
    println(sum(a, b))
    println(test?.let { it(null, null) })
    return sum
}

fun fun15(a: Int, b: (test: String) -> Unit): Unit {
    b("ttt")
    println(a)
}

    fun14(1, 2)
    var s: (String) -> Unit = {
        println(it)
    }
    fun15(6666) { y ->
        println(y)
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值