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