1. 程式人生 > >Kotlin學習筆記--繼承、介面、代理、委託、單例

Kotlin學習筆記--繼承、介面、代理、委託、單例

本例是基於安卓開發環境的。我用的Android Studio 寫的

現在,有這樣3個身份:老大(Activity)、助理(Assistant)、幹活的人(Person)

只要是人,就要吃飯,所有,有個抽象基類(Human)定義吃飯,老大手底下的人,需要幫他收錢和幹活

/**
 * 抽象基類
 */
abstract class Human {

    abstract fun eat()

}
/**
 * 收錢
 */
interface IMoney {

    fun shouqian()

}
/**
 * 辦事
 */
interface IWork {

    fun working()

}

現在,老大給助理和底層人員都分派了任務:收錢和幹活。

/**
 * 助理
 */
class Assistant:Human(),IMoney,IWork {

    override fun eat() {
        println("吃的好")
    }

    override fun shouqian() {
       println("助理,收錢")
    }

    override fun working() {
        println("助理,工作")
    }

}
/**
 * 幹活的人
 */
class Person : Human(), IMoney, IWork {

    override fun eat() {
        println("吃的一般"
) } override fun shouqian() { println("收錢") } override fun working() { println("工作") } }
import android.os.Bundle
import android.support.v7.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle
?)
{ super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) var assistant=Assistant() assistant.eat() assistant.shouqian() assistant.working() var person=Person() person.eat() person.shouqian() person.working() } }

結果就是:各幹個的。

 I/System.out: 吃的好
 I/System.out: 助理,收錢
 I/System.out: 助理,工作

 I/System.out: 吃的一般
 I/System.out: 收錢
 I/System.out: 工作

現在,情況變了,老大對助理說,給我辦2件事,去找XXX把錢收回來;給你100W,把XXX事辦了;助理就去找小弟:給你10W,把事辦漂亮點

這就是委託和代理了。老大委託助理去辦事,助理老大去辦事;而助理把事委託給小弟去辦。小弟助理去辦事

注意關鍵字 by

/**
 * 助理
 */
class Assistant:Human(),IMoney,IWork by Person(){

    override fun eat() {
        println("吃的好")
    }

    override fun shouqian() {
       println("助理,收錢")
    }

}
/**
 * 幹活的人
 */
class Person : Human(), IMoney, IWork {

    override fun eat() {
        println("吃的一般")
    }

    override fun shouqian() {

    }

    override fun working() {
        println("給了我10W辦事")
    }
}

這次,老大直接和助理說的,沒有對小弟說,所有程式碼就是

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var assistant=Assistant()
        assistant.eat()
        assistant.shouqian()
        assistant.working()

    }
}

結果:

 I/System.out: 吃的好
 I/System.out: 助理,收錢
 I/System.out: 給了我10W辦事

說明:從這裡可以看出,因為助理通過“by”把辦事委託給了小弟,所有,他的程式碼中可以不寫working相關,小弟那裡會去做

如果因為一些特殊原因,助理那裡需要執行“辦事”呢?

/**
 * 助理
 */
class Assistant:Human(),IMoney,IWork by Person(){

    override fun eat() {
        println("吃的好")
    }

    override fun shouqian() {
       println("助理,收錢")
    }

    override fun working() {
        println("助理,給了我100W辦事")
        Person().working()
        println("花了10W,辦了100W的事")
    }

}

結果:

 I/System.out: 吃的好
 I/System.out: 助理,收錢
 I/System.out: 助理,給了我100W辦事
 I/System.out: 給了我10W辦事
 I/System.out: 花了10W,辦了100W的事

注意:一定要有Person().working(),要手動指派一下。如果助理辦事的程式碼寫成了

/**
 * 助理
 */
class Assistant:Human(),IMoney,IWork by Person(){

    override fun eat() {
        println("吃的好")
    }

    override fun shouqian() {
       println("助理,收錢")
    }

    override fun working() {
        println("助理,給了我100W辦事")
    }

}

那麼,結果就變成了

 I/System.out: 吃的好
 I/System.out: 助理,收錢
 I/System.out: 助理,給了我100W辦事

小弟就不會去辦事了,即便在最上面用了“by”

說明:我定義2個介面,就是為了順便測試一下多個介面(功能)的委託。

/**
 * 助理
 */
class Assistant:Human(),IMoney by Person(),IWork by Person(){

    override fun eat() {
        println("吃的好")
    }

}

其他不變。同理

特別注意:
上面程式碼中,助理手動去呼叫小弟的辦事方法的程式碼:Person().working()。其實,又在記憶體中,建立了一個小弟。在by Person()的時候建立了一個,在下面的Person().working()中的Person()又建立了一個。指派是隻需要指派給1個小弟的,現在有多個小弟了。不合適。

怎麼修改呢?先來看個例子:
先定義一個Student,就是為了測試物件的唯一性,空物件就行

class Student {
}

然後:

        var s1=Student()

        var s2=Student()

        println("s1==s2 ? ${s1==s2}")

列印結果是:

 s1==s2 ? false

即:2個student不一樣

現在,我們把Student前面的class,變成object

object Student {
}

這時,s1、s2那裡就會報錯。因為寫成object,就是代表在記憶體中,有且只有一個。
改一下Activity那裡,變成了

        var s1=Student

        var s2=Student

        println("s1==s2 ? ${s1==s2}")

Student後面沒有了括號,輸出結果,也成了

 s1==s2 ? true

現在,我們回頭再去改一下Person().working()那裡,
首先,把Person類裡面的class變成object,然後,把助理類中,變成

class Assistant:Human(),IMoney,IWork by Person{

    override fun eat() {
        println("吃的好")
    }

    override fun shouqian() {
        println("助理,收錢")
    }

    override fun working() {
        println("助理,給了我100W辦事")
        Person.working()
        println("花了10W,辦了100W的事")
    }

}

注意:
1、繼承和介面的實現,都是在類名後面,和類名用冒號分割,繼承的類和介面直接用逗號分割
2、繼承的類後面要加括號,如:Human(),介面直接寫介面名就行,如:IMoney

3、如果,想繼承2個類呢?會報錯的。如下
我再定義一個:

abstract class AAA {

    abstract fun haha()

}
/**
 * 助理
 */
class Assistant:Human(),AAA(),IMoney by Person(),IWork by Person(){

    override fun eat() {
        println("吃的好")
    }

    override fun haha() {

    }

}

AAA()那裡會報錯:

Only one class may appear(出現) in a supertype list