Kotlin 中的接口跟java一样 使用 interface 定义
interface CallBack{
fun result()
}
接口实现
class Child : CallBack{
override fun result() {
}
}
实现多个接口时,可能会遇到同一方法继承多个实现的问题。例如(官网的例子)两个接口定义的方法名字一样
interface A {
fun foo() { print("A") }
fun bar()
}
interface B {
fun foo() { print("B") }
fun bar() { print("bar") }
}
class C : A {
override fun bar() { print("bar") }
}
class D : A, B {
override fun foo() {
super.foo()
super.foo()
}
override fun bar() {
super.bar()
}
}
上面 A ,B中有相同的方法 D分别实现了A,B ,实现方法的时候,需要使用super
或者 super
注明这个方法是哪个接口的
可见性修饰符
Kotlin 中有四个可见性修饰符:private、 protected、 internal 和 public。 如果没有显式指定修饰符的话,默认可见性是 public。
对于包的修饰
对于类和接口的修饰
修饰构造函数 比如我们写单例的时候,一般吧构造函数私有化
class C private constructor(a: Int) { …… }
扩展函数
kotlin 支持函数的扩展 比如给一个String字符串加一个插入的方法
fun String.insert(str:String) : String{
var res = ""
for (s in this){ //this代表的当前字符串
res = res + s+ str
}
return res
}
上面的方法给这个字符串每个字符中间插入另一个字符串就可以如下运用
var string = "abcd"
string = string.insert("e")
Log.i("abcd",string)
结果就是每个字符中间加了一个e字符
12-14 11:20:41.969 28723-28723/com.chs.kotlintext I/abcd: aebecede
不止字符串,kotlin中可以对任何已经存在的对象进行扩展,比如 Array list,TextView……不需要继承,直接扩展方法。
数据类
我们经常创建一些只保存数据的类,比如我们的java bean 。json对应的实体类,在 Kotlin 中,这叫做 数据类 并标记为 data
data class User(val name: String, val age: Int)
泛型
kotlin中的泛型跟java类似
class Box<T>(t: T) {
var value = t
}
val box: Box = Box(1)
如果类型参数可以推断出来,允许省略类型参数
val box = Box(1)
kotlin中没有通配符类型,取而代之的是声明处型变(declaration-site variance)与类型投影(type projections)
kotlin泛型中的 in 关键字和 out关键字
泛型函数 , 类型参数要放在函数名称之前
fun singletonList(item: T): List {
// ……
}
fun T.basicToString() : String { // 扩展函数
// ……
}
委托类 委托跟代理很类似啊
类 Derived 可以继承一个接口 Base,并将其所有共有的方法委托给一个指定的对象: 使用 by 关键字
interface Base {
fun print()
}
class BaseImpl(val x: Int) : Base {
override fun print() { print(x) }
}
class Derived(b: Base) : Base by b //继承接口base 把方法实现委托给 Base的其他实现类
fun main(args: Array<String>) {
val b = BaseImpl(10)
Derived(b).print() // 输出 10
}
委托属性
class Example {
var p: String by Delegate()
}
by 后面的表达式是该 委托 ,属性对应的 get()(和 set())会被委托给它的 getValue() 和 setValue() 方法
class Delegate {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return "$thisRef, thank you for delegating '${property.name}' to me!"
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
println("$value has been assigned to '${property.name} in $thisRef.'")
}
}
延迟属性 Lazy 接受一个 lambda 并返回一个 Lazy
实例的函数
val lazyValue: String by lazy {
println("computed!")
"Hello"
}
fun main(args: Array<String>) {
println(lazyValue)
println(lazyValue)
}
输出
computed!
Hello
Hello
第一次调用 get() 会执行已传递给 lazy() 的 lambda 表达式并记录结果, 后续调用 get() 只是返回记录的结果。默认情况下,对于 lazy 属性的求值是同步锁的(synchronized)
可观察属性 Observable
import kotlin.properties.Delegates
class User {
var name: String by Delegates.observable("" ) {
prop, old, new ->
println("$old -> $new")
}
}
fun main(args: Array) {
val user = User()
user.name = "first"
user.name = "second"
}
结果:
<no name> -> first
first -> second
每当我们给属性赋值时会调用该处理程序(在赋值后执行)。它有三个参数:被赋值的属性、旧值和新值: