Kotlin 面向对象的一些笔记

接口提供默认实现的方法

以前 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.
       }
   }

这样看起来就很舒服了。

你可能感兴趣的:(Kotlin 面向对象的一些笔记)