网站建设须知,天津有哪些有名的网站建设公司,做的单页html怎么放网站,企业手机app开发公司继承类/实现接口 继承类和实现接口都是用的 : #xff0c;如果类中没有构造器 ( constructor )#xff0c;需要在父类类名后面加上 () #xff1a; class MainActivity : BaseActivity(), View.OnClickListener 空安全设计 Kotlin 中的类型分为「可空类型」和「不可空类型」… 继承类/实现接口 继承类和实现接口都是用的 : 如果类中没有构造器 ( constructor )需要在父类类名后面加上 () class MainActivity : BaseActivity(), View.OnClickListener 空安全设计 Kotlin 中的类型分为「可空类型」和「不可空类型」 不可空类型 val editText : EditText 可空类型 val editText : EditText? lateinit 关键字 lateinit 只能修饰 var 可读可写变量 lateinit 关键字声明的变量的类型必须是「不可空类型」 lateinit 声明的变量不能有「初始值」 lateinit 声明的变量不能是「基本数据类型」 在构造器中初始化的属性不需要 lateinit 关键字 平台类型 在类型后面加上一个感叹号的类型是「平台类型」 Java 中可以通过注解减少这种平台类型的产生 Nullable 表示可空类型 NotNull NonNull 表示不可空类型 类型判断 is 判断属于某类型 !is 判断不属于某类型 as 类型强转失败时抛出类型强转失败异常 as? 类型强转但失败时不会抛出异常而是返回 null 获取 Class 对象 使用 类名 ::class 获取的是 Kotlin 的类型是 KClass 使用 类名 ::class.java 获取的是 Java 的类型 setter/getter 在 Kotlin 声明属性的时候 ( 没有使用 private 修饰 ) 会自动生成一个私有属性和 一对公开的 setter/getter 函数。 在写 setter/getter 的时候使用 field 来代替内部的私有属性防止递归栈溢 出。 构造器 使用 constructor 关键字声明构造器 class User {constructor()
} 如果我们在构造器主动调用了父类构造那么在继承类的时候就不能在类的后面加上小括号 constructor(context: Context) : this(context, null)
// 主动调用了父类的构造器
constructor(context: Context, attr: AttributeSet?) : super(context, attr) class CodeView : TextView {constructor(context: Context): super(context)
} 等价 class CodeView(context: Context) : TextView(context) {
} JvmField 生成属性 通过 JvmField 注解可以让编译器只生成一个 public 的成员属性不生成对 应的 setter/getter 函数 Any 和 Unit Any Kotlin 的顶层父类是 Any 对应 Java 当中的 Object 但是比 Object 少了 wait()/notify() 等函数 Unit Kotlin 中的 Unit 对应 Java 中的 void 数组 使用 arrayof() 来创建数组基本数据类型使用对应的 intArrayOf() 等 静态函数和属性 顶层函数 object companion object 其中「顶层函数」直接在文件中定义函数和属性会直接生成静态的在 Java 中通过「文件名Kt」来 访问同时可以通过 file:JvmName 注解来修改这个「类名」。 需要注意这种顶层函数不要声明在 module 内最顶层的包中至少要在一个包中例如 com 。不然不能方便使用。 object 和 companion object 都是生成单例对象然后通过单例对象访问函数和属性的。 JvmStatic 通过这个注解将 object 和 companion object 的内部函数和属性真正生成静态的。 单例模式/匿名内部类 通过 object 关键字实现 // 单例
object Singleton {}
// 匿名内部类
object : OnClickListener {} 字符串模版 通过 ${} 的形式来作为字符串模版 val number 100
val text 向你转账${number}元。
// 如果只是单一的变量可以省略掉 {}
val text2 向你转账$number元。 多行字符串 val s 我是第一行我是第⼆行我是第三行.trimIndent() 区间 200..299 表示 [200, 299] 的区间 ( 包括 299 ) when 关键字 Java 当中的 switch 的高级版分支条件上可以支持表达式 声明接口/抽象类/枚举/注解 // 声明抽象类
abstract class
// 声明接口
interface
// 声明注解
annotation class
// 声明枚举
enum class 编译期常量 在静态变量上加上 const 关键字变成编译期常量 标签 在 Java 中通过 「 类名 .this 例如 Outer.this 」 获取目标类引用 在 Kotlin 中通过「 this 类名 例如 thisOuter 」 遍历 记得让 IDE 来帮助生成 for 循环 for(item in items) 内部类 在 Kotlin 当中内部类默认是静态内部类 通过 inner 关键字声明为嵌套内部类 可见性修饰符 默认的可见性修饰符是 public 新增的可见性修饰符 internal 表示当前模块可见 注释 注释中可以在任意地方使用 [] 来引用目标代替 Java 中的 param link 等。 非空断言 可空类型强制类型转换成不可空类型可以通过在变量后面加上 !! 来达到类型转换。 open/final Kotlin 中的类和函数默认是被 final 修饰的 ( abstract 和 override 例外 ) 除非加上 open 关键字才可以被子类覆写默认方法都是 closed 关闭的不能被重写的 次级构造 class CodeView : TextView {constructor(context: Context): super(context)
} 主构造器 class CodeView constructor(context: Context) : TextView(context) // 如果没有被「可见性修饰符」「注解」标注那么 constructor 可以省略
class CodeView(context: Context) : TextView(context) 成员变量初始化可以直接访问到主构造参数 class CodeView constructor(context: Context) : TextView(context) {val color context.getColor(R.color.white)
} init 代码块 主构造不能包含任何的代码初始化代码可以放到 init 代码块中 class CodeView constructor(context: Context) : TextView(context) {init {//...}
} 在初始化的时候初始化块会按照它们在「文件中出现的顺序」执行。 class CodeView constructor(context: Context) : TextView(context) {init {//...}val paint Paint() // 会在 init{} 之后运行
} 构造属性 在主构造参数前面加上 var/val 使构造参数同时成为成员变量 class User constructor(var username: String?, var password: String?, var code: String?) data class 数据类同时会生成 toString() hashCode() equals() copy() (浅拷贝) componentN() ... 相等比较 结构相等 ( 调用 equals() 比较 ) 引用 相等 (比较 地址值 ) 解构 可以把一个对象「解构」成很多变量 val (code, message, body) response 对应的 Java 代码 val code response.component1()
val message response.component2()
val body response.component3() Elvis 操作符 可以通过 ?: 的操作来简化 if null 的操作 // lesson.date 为空时使用默认值
val date lesson.date ?: 日期待定// lesson.state 为空时提前返回函数
val state lesson.state ?: return// lesson.content 为空时抛出异常
val content lesson.content ?: throw IllegalArgumentException(content expected) when 操作符 when 表达式可以接受返回值多个分支相同的处理方式可以放在一起用逗号分隔 val colorRes when (lesson.state) {Lesson.State.PLAYBACK, null - R.color.playbackLesson.State.LIVE - R.color.liveLesson.State.WAIT - R.color.wait
} when 表达式可以用来取代 if-else-if 链。如果不提供参数所有的分支条件都是布尔表达式 val colorRes when {(lesson.state Lesson.State.PLAYBACK) - R.color.playback(lesson.state null) - R.color.playback(lesson.state Lesson.State.LIVE) - R.color.live(lesson.state Lesson.State.WAIT) - R.color.waitelse - R.color.playback
} operator 通过 operator 修饰「特定函数名」的函数例如 plus 、 get 可以达到重载运算符的效果 lambda 如果函数的最后一个参数是 lambda 那么 lambda 表达式可以放在圆括号之外 lessons.forEach() { lesson : Lesson -// ...
} 如果你的函数传入参数只有一个 lambda 的话那么小括号也可以省略的 lessons.forEach { lesson : Lesson -// ...
} 如果 lambda 表达式只有一个参数那么可以省略通过隐式的 it 来访问 lessons.forEach { // it// ...
} 循环
通过标准函数 repeat() repeat(100) {//..
} 通过区间 for (i in 0..99) {}// until 不包括右边界
for (i in 0 until 100) {} infix 函数 必须是 成员函数 或 扩展函数 必须 只能接受一个参数并且不能有默认值 // until() 函数的源码
public infix fun Int.until(to: Int): IntRange {if (to Int.MIN_VALUE) return IntRange.EMPTYreturn this .. (to - 1).toInt()
} 潜逃函数
Kotlin 中可以在函数中继续声明函数 fun func(){fun innerFunc(){}
} 内部函数可以访问外部函数的参数 每次调用时会产生一个函数对象
注解使用处目标 当某个元素可能会包含多种内容 ( 例如构造属性成员属性 ) 使用注解时可以通过 「注解使用处目标」让注解对目标发生作用例如 file: 、 get: 、 set: 等。 函数简化
可以通过符号 简化原本直接 return 的函数 fun get(key :String) SP.getString(key,null) 函数参数默认值
可以通过函数参数默认值来代替 Java 的函数重载 // 使用 JvmOverloads 对 Java 暴露重载函数
JvmOverloads
fun toast(text: CharSequence, duration: Int Toast.LENGTH_SHORT) {Toast.makeText(this, text, duration).show()
} 扩展函数 扩展函数可以为任何类添加上一个函数从而代替工具类 扩展函数和成员函数相同时成员函数优先被调用 扩展函数是静态解析的在编译时就确定了调用函数 ( 没有多态 )
函数类型
函数类型由「传入参数类型」和「返回值类型」组成用「 - 」连接传入参数需要用「 () 」如果返回值为 Unit 不能省略 函数类型实际是一个接口如果需要将函数作为参数传递时可以通过「 ::函数名 」或者「匿名函数」或者使用 「 lambda 」
内联函数
内联函数配合「函数类型」可以减少「函数类型」生成的对象使用 inline 关键字声明的函数是「内联函数」在「编译时」会将「内联函数」中的函数体直接插入到调用处。所以在写内联函数的时候需要注意尽量将内联函数中的代码行数减少
部分禁用内联
noinline 可以禁止部分参数参与内联编译 inline fun foo(inlined: () - Unit, noinline notInlined:() - Unit) {//......
} 具体化的类型参数
因为内联函数的存在我们可以通过配合 inline reified 达到「真泛型」的效果 val RETROFIT Retrofit.Builder().baseUrl(https://api.github.com/).build()inline fun reified T create(): T {return RETROFIT.create(T::class.java)
}val api createAPI() 抽象属性 在 Kotlin 中我们可以声明抽象属性子类对抽象属性重写的时候需要重写对应的 setter/getter 属性委托 有些常见的属性操作我们可以通过委托的方式让它只实现一次例如 lazy 延迟属性值只在第一次访问的时候计算 observable 可观察属性属性发生改变时的通知 map 集合将属性存在一个 map 中
对于一个只读属性(即 val 声明的)委托对象必须提供一个名为 getValue() 的函数
对于一个可变属性(即 var 声明的)委托对象同时提供 setValue() 、 getValue() 函数
类委托 可以通过类委托的模式来减少继承类委托的编译器会优先使用自身重写的函数而不是委托对象的函数 interface Base {fun print()
}
class BaseImpl(val x: Int) : Base {override fun print() {print(x)}
}// Derived 的 print 实现会通过构造参数中的 b 对象来完成。
class Derived(b: Base) : Base by b Kotlin 标准函数apply、also、run、let
使用时可以通过简单的规则作出一些判断 需要返回自身 - 从 apply 和 also 中选 作用域中使用 this 作为参数 ---- 选择 apply 作用域中使用 it 作为参数 ---- 选择 also 不需要返回自身 - 从 run 和 let 中选择 作用域中使用 this 作为参数 ---- 选择 run 作用域中使用 it 作为参数 ---- 选择 let
apply 适合对一个对象做附加操作的时候
let 适合配合判空的时候 (最好是成员变量而不是局部变量局部变量更适合用 if )
with 适合对同一个对象进行多次操作的时候