今天继续kotlin
相关的知识点和常考考点,通过这些问答相信你也能更一步了解Kotlin
。
可以定义同名的扩展方法吗
在同一个包名下,是不可以定义相同类相同方法名的扩展方法的。但是,在不同包名下,是可以定义的。
比如我在不同的包名下定义了相同的扩展方法:
代码语言:javascript复制//Utils2.kt
package com.example.studynote.kotlin
fun Activity.showToast(msg:String){
Toast.makeText(this,msg,Toast.LENGTH_LONG).show()
}
//Utils.kt
package com.example.studynote
fun Activity.showToast(msg:String){
Toast.makeText(this,msg,Toast.LENGTH_SHORT).show()
}
具体会用哪个呢?就要看你导入的包是哪个了~
扩展方法可以覆盖掉某个类的已有方法吗
肯定是不能的,如果一个类的扩展方法和它已有方法同名,是可以编译过的。
但是调用的时候会优先调用
类中本来就有的方法,而不是扩展方法。
kotlin中有没有用到;的时候
kotlin中一般会把;
省略,但是有两种情况还是会用到:
- 枚举中,如果有方法的情况,必须用
;
来分割枚举常量列表和方法
enum class Color {
RED,
BLACK,
BLUE,
GREEN,
WHITE;
fun getTopColor():Color {
return BLACK
}
}
- 两个表达式在一行的时候,当然这种有点累赘,为啥要写成一行呢是吧:
var test="nihao" ; var test2="heihei"
let、apply、with、run
- let 默认当前这个对象作为闭包的it参数,返回值为函数最后一行,或者return
fun getInt():Int{
"jimu".let {
println(it.length)
return 0
}
}
- apply 在apply函数范围内,可以任意调用该对象的任意方法,并返回该对象
fun getInt(): Int {
return ArrayList<String>().apply {
add("jimu")
}.size
}
- with 返回值是最后一行,这点类似let。可以直接调用对象的方法,这点类似apply。
fun getInt(): Int {
return with(ArrayList<String>()){
add("jimu")
size
}
}
- run run和with很像,可以调用对象的任意函数,返回值是最后一行
fun getInt(): Int {
return ArrayList<String>().run{
add("jimu")
size
}
}
lateinit和by lazy
上篇说过,Kotlin
有空限制,所以有些变量如果不想设置为空的时候初始化该怎么做呢?这就用到延迟初始化了,lateinit和by lazy
都能实现。
- lateinit
lateinit
用于修饰var变量,它会让编译器暂时忽略初始化这个事情,到后面用的时候我们在进行初始化,但是不能用到基本数据类型,比如int,double
这种。
lateinit var test: String
- by lazy
by lazy
用于val
类型的变量,它会暂时不进行初始化,并且在第一次使用的时候自动调用我们设置好的表达式进行初始化。
val str by lazy {
println("Init lazy")
"Hello World"
}
构造函数
kotlin中构造函数分为主构造函数和次构造函数。
- 主构造函数
主构造函数没有函数体,直接定义在类名后。每个类都会默认带一个不带参数的构造函数,也可以直接定义参数,如果需要在构造函数中进行初始化工作,可以用init
关键字:
class Student {
}
class Student(var name: String) {
init {
Log.e(TAG,"name=$name")
}
}
class Student constructor(var name: String) {
init {
Log.e(TAG,"name=$name")
}
}
- 次构造函数
除了类名后这种主构造函数,其他的构造函数方法就是通过constructor
关键字来定义次构造函数,一个类可以定义多个次构造函数。如果主构造函数和次构造函数同时存在的时候,次构造函数必须调用主构造函数。
class Student{
private val username: String
constructor(username: String){
this.username = username
}
}
class Student(username: String) {
private var username: String
private var age: Int
init {
this.username = username
this.age = 10
}
constructor(username: String, age: Int) : this(username) {
this.age = age
}
}
协程
Kotlin协程
是对线程的一种封装,同样是用来解决并发任务(异步任务)的方案,可以理解为一种线程框架,特点是挂起时不需要阻塞线程,更好的解决了线程切换,魔鬼调用的问题。
简单举个例子,具体的说明大家可以翻翻以前的文章——协程三问。
代码语言:javascript复制
GlobalScope.launch(Dispatchers.Main) {
var name = ioTask()
updateUI(name)
var name1 = ioTask()
updateUI(name1)
var name2 = ioTask()
updateUI(name2)
}
private suspend fun ioTask(): String {
var name = ""
withContext(Dispatchers.IO) {
//耗时操作,比如网络接口访问
name = "jimu"
}
return name
}
GlobalScope.launch
去开启一个协程Dispatchers.Main
表示运行在主线程suspend
关键字用于标记挂起函数的关键字withContext
函数用来构建一个协程作用域,可以标明作用线程,比如这里的Dispatchers.IO。这个函数必须在挂起函数或者协程中执行
感谢大家的阅读,有一起学习的小伙伴可以关注下公众号—
码上积木
❤️❤️ 每日三问知识点/面试题,积少成多。