1.kotlin的引入
首先打开Android Studio,File-New-New Project,选中include Kotlin Support
(如果,新建一个项目时忘记include 或者 原有项目新引入kotlin时
1⃣️在project的build.gradle
buildscript中加入 ext.kotlin_version = '1.2.41'
dependencies中加入 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
2⃣️在模块的build.gradle中
dependencies中加入 implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
之后就可以愉快的使用kotlin了。
2.kotlin的语法
1.变量
1⃣️分类,val只有get方法,var有set和get两种方法
2⃣️初始化
声明一个属性的完整语法:
|
初始器(initializer,标蓝的部分)、getter 和 setter 都是可选的。属性类型如果可以从初始器 (或者从其 getter 返回值)中推断出来,也可以省略;
setter 参数的名称是 value
,但是支持自定义:
|
!!!backing field(翻译成 “幕后字段,也有影子的那种含义”),每次赋值取值都不是直接取变量本身,而且操作field,否则容易造成循环
|
一个陷阱,会造成循环引用:
|
2.类声明
1⃣️可见性:所有的kotlin类默认都是public的
public:所有类可见(默认的)
private:只有该类及其中成员可见
protected:该类及子类可见
internal:该模块可见
2⃣️可继承性
新建一个kotlin类,所有的类(接口除外)默认都是不可继承的(类似于java中的final属性),如果想继承该类,要加上open字段
3⃣️构造函数(感觉很重要),一个类可以有一个主构造函数和一个或多个次构造函数。
1.主构造函数
- 就在类头中,如果无open等修饰字段或注解等,可以省略constructor字段;主构造函数中无代码,初始化块可以放在init{}中。
- 若派生类有一个主constructor,其基类必须用基类的主构造函数,就地的初始化。 class B(var view: View): A(view: View){}
- 若主构造函数,所有参数都有默认值,则编译器会生成一个额外的无参的构造函数。
- 设计一个基类时,避免在构造函数/属性初始化器及init中使用open字段
2.次构造函数
若存在主构造函数,则需要自己委托或通过其他构造函数委托给主构造函数。次级构造函数,在所有init执行之后,第一个执行。
data class Person(val name: String){
var age: Int = 0
}
则计算hashCode() copy() 和 toString()等方法只用到name进行计算
初始化一个Person实例 var person: Person = Person() 没有new字段
3.方法
1⃣️结构
1.带有两个 Int
参数、返回 Int
的函数:
fun sum(a: Int, b: Int): Int {
return a + b
}
2. 将表达式作为函数体、返回值类型自动推断的函数:
fun sum(a: Int, b: Int) = a + b
3. 函数返回无意义的值:
fun printSum(a: Int, b: Int): Unit {
println("sum of $a and $b is ${a + b}")
}
4.Unit
返回类型可以省略:
fun printSum(a: Int, b: Int) {
println("sum of $a and $b is ${a + b}")
}
2⃣️所有方法默认是不可以被继承的,若想被重写,要加上open字段,重写方法前要加上override
例如
open class A {
open fun write(){
println("A")
}
}
class B() :A() {
override fun write(){ //标记为override的方法,本身就是open的,若想禁止被重写,则加final
println("B")
}
}
2⃣️若继承或实现的类有相同的方法,则需要消除歧义
例如
open class A {
open fun write(){
println("A")
}
}
interface B{ //接口默认为open的,方法也默认为open的
fun write(){
println("B")
}
}
class C(): A(), B{
override fun write(){
super<A>.write() //则输出的A
}
}
4.代码规范
1⃣️相关的方法放在一起
2⃣️方法命名规范 verb. 或 verb.+n.
3⃣️遇到过于长的单词,缩写前面字母并大写
如果缩写字母是两个,则都大写,如IOStream
如果多于两个,则只大写第一个缩写字母,如XmlFormatter
5.扩展
能够扩展一个类的新功能而无需继承该类或使用像装饰者这样的任何类型的设计模式。
1⃣️一开始并没有读懂这句话的意思,然而用上了之后才发现无比的方便!
新建一个类,写入方法
fun Context.myToast(msg: String) { Toast.makeText(this, msg, Toast.LENGTH_SHORT).show() }
之后在任意的Context,如Activity中,就可以直接使用下面的语句使用“升级版”toast了。
myToast("hello world")
2⃣️除了传入简单的字符串等,还可以传入一个方法
fun Context.myToast(msg: String, flag: Boolean, duration: () -> Unit) { if(flag) duration() //可以通过,flag的值,控制方法是否执行 }
使用如下,则只有在flag为true的情况下,才会打印出log
myToast("hello Baby", true) { Log.d("myToast", "value=" + true) } myToast("hello Baby", false) { Log.d("myToast", "value=" + false) } myToast("hello Baby", true) { Log.d("myToast", "value=" + true) }