buildscript {
ext.kotlin_version = '1.0.0'
dependencies {
classpath 'me.tatarka:gradle-retrolambda:3.2.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'me.tatarka.retrolambda'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
- 推荐安装Kotlin Extensions For Android
Lambda
- 通过表达式代替
@Functionalinterface
(只包含一个方法的接口) - 如果主体只有一条语句,可省略
{}
、return
、语句后面的;
// 参数类型可写可不写
view.setOnClickListener((view) -> {});
基础
变量
变量名在前,变量类型在后
如果声明的时候赋值了就不用指定类型,会自动类型推导
-
val(final 常量)
val a : Int = 1 // final int a = 1;
-
变量默认都是
@NotNull
的,在类型后面加上?
可以指定为@Nullable
var b = 1 // int b = 1; var s : String? // 可以为null
可以return null的函数,其返回类型都要加上?
数组
类型安全
-
is
用于类型判断,相当于instanceof
fun getStringLength(obj: Any) : Int? { if (obj is String) { // is判断内自动转为String类型,不需要强转 return obj.length } // 离开类型判断分支后,仍然是Any类型 return null; }
-
字符串模版(EL表达式)
"Hello ${name}"
-
if else替代三目运算符
fun max(a : Int, b :Int) : Int? = if (a > b) a else b
函数
-
如果函数返回Unit类型,可以忽略掉
fun main(args : Array<String>): Unit { // String[] println("hello world!"); // 分号可以省略 }
-
函数体只有一个表达式时可省略括号,返回值自动自动推断
fun sum(a : Int, b : Int) = a + b;
相等
-
引用相等
a === b // a.identityEqual(b)
-
结构相等
a == b // a?.equals(b) ?: b === null
For
-
in
等价于foreachfor ((k, v) in map) { println("$k -> $v") }
-
indices
下标索引fun main(args : Array<String>) { for(i in args.indices) { print(args[i]) } }
-
sizei()
fun main(args : Array<String>) { var i = 0 while(i < args.size()) { print(args[i++]) } }
OOP
默认都是
final
类-
package import和java一致,如果出现导入报名冲突可以使用
as
import foo.Bar import bar.Bar as bBar
构造函数
-
主构造函数只有一个,是类头的一部分跟在类名后面
-
主构造函数的参数
class Person (firstName: String) { init {} // 主构造函数初始化代码 } // 等价于 public final class Person { public Person(String name) { // init{} } }
-
主构造函数 + 属性
class Person(val name: String, var age: Int) {} // 等价于 public final class Person { private final String name; private int age; public Person(@NotNull String name, int age) {} // getter setter }
如果一个类没有声明任何构造函数,将会生成一个不带参数的主构造函数
-
-
二级构造函数,使用constructor
class Person(val name: String) { constructor(name: String, parent: Person): this(name) {} }
-
创建实例:没有<del>
new
</del>关键字,直接调用构造函数val person = Pserson("ss");
属性
要使用属性只需要使用名称引用即可,就相当于java中的public
字段
继承:
所有类的共同父类Any
,不属于java.lang.Object
,没有任何成员变量,甚至没有equals()
、hashCode()
、toString()
普通类
-
继承的类有主构造函数
open class Base(p: Int) {} class Derived(p: Int) : Base(p) {}
-
没有主构造函数,那么每个二级构造函数使用
super
或者委托给另一个构造函数class MyView : View { constructor(context: Context) : super(context) { } constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { } }
- 父类的函数必标注
open
(去掉java中的final关键字)否则子类不允许定义同名函数;因此父类类头上也要标注open
- 函数必须加上
override
标注才能重写父类方法
抽象类 & 接口
单例
object SDKFactory {
fun say(name : String) {
println("hello ${name}")
}
}
SDKFactory.say("CatDog") // SDKFactory.INSTANCE.say("CatDog")
public final class SDKFactory {
public static final SDKFactory INSTANCE;
private SDKFactory() {
INSTANCE = (SDKFactory)this;
}
static {
new SDKFactory();
}
public final void say(@NotNull String name) {
// ..
}
}