接口提供默认实现的方法
以前 Java 中,我们要是在接口中增加一个方法,那么所有实现这个接口的类都必须要重写这个方法,但是在 Kotlin 中我们可以定义一个带有方法实现的接口,那么之前实现过该接口的类,就可以不用实现这个新方法。例如:
interface Test {
fun sayHi();
fun code(){
print("coding")
}
}
//实现接口,我们可以不实现接口里已经默认实现的方法
class MainActivity : AppCompatActivity(),Test {
override fun sayHi() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
by lazy , lateinit
by lazy:
1.变量必须是引用不变的,不能通过 var 来声明
2.首次调用时,被赋值,一旦被赋值,后续不能更改
3.系统会默认给 lazy 属性加上同步锁,也就 LazyThreadSafetyMode.SYNCHRONIZED,当然也可以更改。
/**
* Locks are used to ensure that only a single thread can initialize the [Lazy] instance.
*/
SYNCHRONIZED,
/**线程并行执行
* Initializer function can be called several times on concurrent access to uninitialized [Lazy] instance value,
* but only the first returned value will be used as the value of [Lazy] instance.
*/
PUBLICATION,
/**不做线程保证
* No locks are used to synchronize an access to the [Lazy] instance value; if the instance is accessed from multiple threads, its behavior is undefined.
*
* This mode should not be used unless the [Lazy] instance is guaranteed never to be initialized from more than one thread.
*/
NONE,
多继承问题
1.内部类
关键字 inner,因为内部类可以继承一个与外部类无关的类
2.使用委托代替多继承
通过关键字 by 实现委托,替代多继承
(类似Java实现多接口),委托是用一个具体的类去实现方法的逻辑
data class
简化 Java Bean,其中多了 copy,componentN
copy:
看看下面熟悉的代码,猜猜会打印什么
Test t1 = new Test("blue");
Test t2 = t1;
t2.setColor("red")
System.out.println(t1.getColor());
//red
理由 t2 引用了 t1,也就是浅拷贝,除了基本类型,其他都是只是一个引用而已,那么一个设置了值另外一个自然也就更着变了。
在 koltin 中 copy 是提供了一个简洁的复制一个对象的做法,它也是浅拷贝的一种方式,所以在使用的时候要主要 数据的属性使用 var 还是 **val,如果是 可变属性 **var 的话,就不能保证会不会出现引用更改。
val test = Test("blue")
val test2 = test.copy("red")
componentN
可以理解为类的属性的值,N 代表第几个值,比如 component1 就是代表第一个参数。作用就是可以将类的属性赋值给变量。
看看 Java 代码:
String test = "say_hi"
String[ ] value= test .split("_")
String valueOne = value[0]
取一个值要分好几步,那么在 Kotlin 中呢
val(valueOne,valueTwo) = test .split("_")
伴生对象
跟 Java 中的 static 修饰符效果一样,全局只有一个单例,需要声明在类的内部,相较于 Java 事类中的结构更加清晰
companion object{
//类中的所有静态变量和静态方法都可以声明在这里
}
单例:
既然全局只有一个单例,那么就可以用做 单例模式来使用了,单例模式的特点,构造方法私有,提供一个静态方法来创建一个单例的对象,那么结合 by lazy 我们就可以创建一个线程安全的单例了:
class Singleton private constructor() {
companion object {
val instance: Singleton by lazy { Singleton() }
}
}
object 表达式
解决匿名内部类的问题,例如写的最多的就是 各种监听事件了,用 object 可以让匿名内部类更加的优雅
var testClick = object : View.OnClickListener {
override fun onClick(v: View?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
不过有人会说 使用 lambda 表达式不是更优雅嘛,确实,在这种只需要实现一个方法的时候 lambda 会更优雅一点,但是在有多个方法的时候,为觉得 object 表达式的优势就出来了
animator.addListener(testAnimator)
var testAnimator = object : Animator.AnimatorListener {
override fun onAnimationRepeat(animation: Animator?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onAnimationEnd(animation: Animator?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onAnimationCancel(animation: Animator?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onAnimationStart(animation: Animator?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
这样看起来就很舒服了。