Android面试Kotlin基础篇(六)

问:Kotlin的两种延迟初始化,他们的区别是什么?

答:一种是lateinit var,一种是by lazy
lateinit var: 它只能用来修饰类属性,不能用来修饰局部变量,并且只能用来修饰对象,不能用来修饰基础数据类型(基础数据类型在类加载后的准备阶段会自动给一个初始值)。作用于编译器时,不去检查有没有初始化对象,但是可能在运行时报错,最好使用isInitialized来判断是否已经初始化。
by lazy: 它其实是一种代理对象,在使用时才初始化,by lazy可以使用于类属性或者局部变量,且只能修饰val不可变对象,类似于Java中的final对象。

虽然两者都可以推迟属性初始化的时间,但是lateinit var只是让编译期忽略对属性未初始化的检查,后续在哪里以及何时初始化还需要开发者自己决定。
而by lazy真正做到了声明的同时也指定了延迟初始化时的行为,在属性被第一次被使用的时候能自动初始化。

问:let,apply,run,with,aslo,等函数的区别(https://blog.csdn.net/u013064109/article/details/78786646

答:with 它是将某对象作为函数的参数,在函数块内中使用this代表对象,this可以省略。返回值为函数块的最后一行或指定return表达式。适用于调用同一个类的多个方法时,可以省去类名重复,直接调用类的方法即可。如:

  fun testWith() {
    // fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
    with(ArrayList<String>()) {
        add("testWith")
        add("testWith")
        add("testWith")
        println("添加结果"+this.toString())    //打印结果:添加结果[testWith, testWith, testWith]
        "返回结果"+this.toString()    //作为with函数的返回结果
    }.let { println(it) }    //打印结果:返回结果[testWith, testWith, testWith]
}

let 默认当前这个对象作为闭包的it参数,返回值是函数里面最后一行,或者指定return。最常用的场景就是使用let函数处理需要针对一个可null的对象统一做判空处理

fun testLet(): Int {
    // fun <T, R> T.let(f: (T) -> R): R { f(this)}
    "testLet".let {
        println(it)    //打印结果:testLet
        return 1    //作为结果
    }
}

apply 调用某对象的apply函数,在函数范围内,可以任意调用该对象的任意方法,并返回该对象。apply一般用于一个对象实例初始化的时候,需要对对象中的属性进行赋值

fun testApply() {
    // fun <T> T.apply(f: T.() -> Unit): T { f(); return this }
    ArrayList<String>().apply {
        add("testApply")
        println("this = " + this)    //打印结果:this=[testApply]
    }.let { println(it) }  //打印结果 [testApply]
}

run run函数和apply函数很像,只不过run函数是使用最后一行的返回,apply返回当前自己的对象。with和let的结合体,弥补了let中必须使用it来代表对象的问题,也可以做判空处理

fun testRun() {
    // fun <T, R> T.run(f: T.() -> R): R = f()
    "testRun".run {
        println("this = " + this)    // this = testRun
    }.let { println(it) }      // kotlin.Unit
}

aslo 与let类似,执行代码块,但返回this自身,

fun testAslo(){
  //fun <T> T.also(block: (T) -> Unit): T {}
  var aslo = "testAslo".aslo{
    println(it)    //打印:testAslo
  }
  println(aslo)     //打印:testAslo
}
问:Kotlin中如何实现静态方法

答:单例类、companion object、顶层方法等可以实现静态方法效果,但是Java中要调用Kotlin中的静态方法需要在companion object中的方法之上加上@JvmStatic 注解,使得方法变成真正的静态方法。

//1、单例类
object Utils{
  //使用Utils.doAction
  fun doAction(){
  }
}

//companion object
class Utils{
  //使用时  Utils.doAction()
  companion object{
    fun doAction(){
    }
  }
}

//顶层方法---在任意一个kt文件中写一个方法即为顶层方法,在程序的任意一个地方直接使用
//新建Utils.kt文件
fun doAction(){
  //在任意地方都可以直接调用doAction() 
}

//真正的静态方法:
class Utils{
  //使用时  Utils.doAction()
  companion object{
    @JvmStatic    //增加方法注解,在编译时会编译成静态方法
    fun doAction(){
    }
  }
}
问:Kotlin中密封类的作用

答:密封类:sealed class 密封类是一个可以继承的类。密封类变量作为参数、条件时,Kotlin编译器会自动检查该类有哪些子类。密封类及其所有子类只能定义在同一个文件的顶层位置,不能嵌套在其他类中。例如:

//新建一个Result.kt文件 
interface Result
class Success(val msg:String):Result
class Failure(val error:Exception):Result
//使用时,如果新增一种未知状态继承如:class Unknown(val error:Exception):Result
fun getResult(result:Result) = when(result){
  is Success ->{result.msg}
  is Failure ->{result.error.message}
  //此处如果不加is Unknow,不会提示报错,但是运行时有可能执行else抛出异常了
  else ->{throw IllegalArgumentException}  //如果非密封类,必需编写这个无用的分支
}

//------修改为密封类
sealed class Result      //接口修改密封类 sealed class 
class Success(val msg:String):Result()    //Result是一个普通的可继承类,最后需要()
class Failure(val error:Exception):Result()
//使用时--如果增加一个子类,则在使用的地方会显示提醒异常
fun getResult(result:Result) = when(result){
  is Success ->{result.msg}
  is Failure ->{result.error.message}
}
问:Kotlin中的扩展函数

答:扩展函数表示即使在不修改某个类的源代码的情况下,仍然可以打开这个类,向该类添加新的函数。最好定义为顶层方法,使其作用于全局。

//扩展函数的定义
fun 类名.方法名(参数1:类型,参数2:类型):返回类型{
  
}
//例如:
//定义吐司方法
fun String.showToast(context:Context){
  Toast.makeText(context, this,Toast.LENGTH_LONG)
}

//使用
"测试Toast".showToast(this)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,458评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,454评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,171评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,062评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,440评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,661评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,906评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,609评论 0 200
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,379评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,600评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,085评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,409评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,072评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,088评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,860评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,704评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,608评论 2 270

推荐阅读更多精彩内容