Kotlin学习笔记--继承、接口、代理、委托、单例

本例是基于安卓开发环境的。我用的Android Studio 写的

现在,有这样3个身份:老大(Activity)、助理(Assistant)、干活的人(Person)

只要是人,就要吃饭,所有,有个抽象基类(Human)定义吃饭,老大手底下的人,需要帮他收钱和干活

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

    abstract fun eat()

}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
/**
 * 收钱
 */
interface IMoney {

    fun shouqian()

}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
/**
 * 办事
 */
interface IWork {

    fun working()

}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

现在,老大给助理和底层人员都分派了任务:收钱和干活。

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

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

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

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

}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
/**
 * 干活的人
 */
class Person : Human(), IMoney, IWork {

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

    override fun shouqian() {
        println("收钱")
    }

    override fun working() {
        println("工作")
    }
}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
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()

    }
}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

结果就是:各干个的。

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

 I/System.out: 吃的一般
 I/System.out: 收钱
 I/System.out: 工作
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

现在,情况变了,老大对助理说,给我办2件事,去找XXX把钱收回来;给你100W,把XXX事办了;助理就去找小弟:给你10W,把事办漂亮点

这就是委托和代理了。老大委托助理去办事,助理老大去办事;而助理把事委托给小弟去办。小弟助理去办事

注意关键字 by

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

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

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

}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
/**
 * 干活的人
 */
class Person : Human(), IMoney, IWork {

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

    override fun shouqian() {

    }

    override fun working() {
        println("给了我10W办事")
    }
}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

这次,老大直接和助理说的,没有对小弟说,所有代码就是

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()

    }
}

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

结果:

 I/System.out: 吃的好
 I/System.out: 助理,收钱
 I/System.out: 给了我10W办事
    
    
  • 1
  • 2
  • 3

说明:从这里可以看出,因为助理通过“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的事")
    }

}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

结果:

 I/System.out: 吃的好
 I/System.out: 助理,收钱
 I/System.out: 助理,给了我100W办事
 I/System.out: 给了我10W办事
 I/System.out: 花了10W,办了100W的事
    
    
  • 1
  • 2
  • 3
  • 4
  • 5

注意:一定要有Person().working(),要手动指派一下。如果助理办事的代码写成了

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

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

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

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

}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

那么,结果就变成了

 I/System.out: 吃的好
 I/System.out: 助理,收钱
 I/System.out: 助理,给了我100W办事
    
    
  • 1
  • 2
  • 3

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

说明:我定义2个接口,就是为了顺便测试一下多个接口(功能)的委托。

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

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

}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

其他不变。同理

特别注意:
上面代码中,助理手动去调用小弟的办事方法的代码:Person().working()。其实,又在内存中,创建了一个小弟。在by Person()的时候创建了一个,在下面的Person().working()中的Person()又创建了一个。指派是只需要指派给1个小弟的,现在有多个小弟了。不合适。

怎么修改呢?先来看个例子:
先定义一个Student,就是为了测试对象的唯一性,空对象就行

class Student {
}
    
    
  • 1
  • 2

然后:

        var s1=Student()

        var s2=Student()

        println("s1==s2 ? ${s1==s2}")
    
    
  • 1
  • 2
  • 3
  • 4
  • 5

打印结果是:

 s1==s2 ? false
    
    
  • 1

即:2个student不一样

现在,我们把Student前面的class,变成object

object Student {
}
    
    
  • 1
  • 2

这时,s1、s2那里就会报错。因为写成object,就是代表在内存中,有且只有一个。
改一下Activity那里,变成了

        var s1=Student

        var s2=Student

        println("s1==s2 ? ${s1==s2}")
    
    
  • 1
  • 2
  • 3
  • 4
  • 5

Student后面没有了括号,输出结果,也成了

 s1==s2 ? true
    
    
  • 1

现在,我们回头再去改一下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
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

注意:
1、继承和接口的实现,都是在类名后面,和类名用冒号分割,继承的类和接口直接用逗号分割
2、继承的类后面要加括号,如:Human(),接口直接写接口名就行,如:IMoney

3、如果,想继承2个类呢?会报错的。如下
我再定义一个:

abstract class AAA {

    abstract fun haha()

}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
/**
 * 助理
 */
class Assistant:Human(),AAA(),IMoney by Person(),IWork by Person(){

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

    override fun haha() {

    }

}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

AAA()那里会报错:

Only one class may appear(出现) in a supertype list
    
    
  • 1

转自:https://blog.csdn.net/u014620028/article/details/78521114

本例是基于安卓开发环境的。我用的Android Studio 写的

现在,有这样3个身份:老大(Activity)、助理(Assistant)、干活的人(Person)

只要是人,就要吃饭,所有,有个抽象基类(Human)定义吃饭,老大手底下的人,需要帮他收钱和干活

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

    abstract fun eat()

}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
/**
 * 收钱
 */
interface IMoney {

    fun shouqian()

}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
/**
 * 办事
 */
interface IWork {

    fun working()

}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

现在,老大给助理和底层人员都分派了任务:收钱和干活。

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

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

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

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

}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
/**
 * 干活的人
 */
class Person : Human(), IMoney, IWork {

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

    override fun shouqian() {
        println("收钱")
    }

    override fun working() {
        println("工作")
    }
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
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()

    }
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

结果就是:各干个的。

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

 I/System.out: 吃的一般
 I/System.out: 收钱
 I/System.out: 工作
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

现在,情况变了,老大对助理说,给我办2件事,去找XXX把钱收回来;给你100W,把XXX事办了;助理就去找小弟:给你10W,把事办漂亮点

这就是委托和代理了。老大委托助理去办事,助理老大去办事;而助理把事委托给小弟去办。小弟助理去办事

注意关键字 by

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

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

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

}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
/**
 * 干活的人
 */
class Person : Human(), IMoney, IWork {

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

    override fun shouqian() {

    }

    override fun working() {
        println("给了我10W办事")
    }
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

这次,老大直接和助理说的,没有对小弟说,所有代码就是

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()

    }
}

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

结果:

 I/System.out: 吃的好
 I/System.out: 助理,收钱
 I/System.out: 给了我10W办事
  
  
  • 1
  • 2
  • 3

说明:从这里可以看出,因为助理通过“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的事")
    }

}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

结果:

 I/System.out: 吃的好
 I/System.out: 助理,收钱
 I/System.out: 助理,给了我100W办事
 I/System.out: 给了我10W办事
 I/System.out: 花了10W,办了100W的事
  
  
  • 1
  • 2
  • 3
  • 4
  • 5

注意:一定要有Person().working(),要手动指派一下。如果助理办事的代码写成了

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

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

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

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

}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

那么,结果就变成了

 I/System.out: 吃的好
 I/System.out: 助理,收钱
 I/System.out: 助理,给了我100W办事
  
  
  • 1
  • 2
  • 3

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

说明:我定义2个接口,就是为了顺便测试一下多个接口(功能)的委托。

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

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

}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

其他不变。同理

特别注意:
上面代码中,助理手动去调用小弟的办事方法的代码:Person().working()。其实,又在内存中,创建了一个小弟。在by Person()的时候创建了一个,在下面的Person().working()中的Person()又创建了一个。指派是只需要指派给1个小弟的,现在有多个小弟了。不合适。

怎么修改呢?先来看个例子:
先定义一个Student,就是为了测试对象的唯一性,空对象就行

class Student {
}
  
  
  • 1
  • 2

然后:

        var s1=Student()

        var s2=Student()

        println("s1==s2 ? ${s1==s2}")
  
  
  • 1
  • 2
  • 3
  • 4
  • 5

打印结果是:

 s1==s2 ? false
  
  
  • 1

即:2个student不一样

现在,我们把Student前面的class,变成object

object Student {
}
  
  
  • 1
  • 2

这时,s1、s2那里就会报错。因为写成object,就是代表在内存中,有且只有一个。
改一下Activity那里,变成了

        var s1=Student

        var s2=Student

        println("s1==s2 ? ${s1==s2}")
  
  
  • 1
  • 2
  • 3
  • 4
  • 5

Student后面没有了括号,输出结果,也成了

 s1==s2 ? true
  
  
  • 1

现在,我们回头再去改一下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
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

注意:
1、继承和接口的实现,都是在类名后面,和类名用冒号分割,继承的类和接口直接用逗号分割
2、继承的类后面要加括号,如:Human(),接口直接写接口名就行,如:IMoney

3、如果,想继承2个类呢?会报错的。如下
我再定义一个:

abstract class AAA {

    abstract fun haha()

}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
/**
 * 助理
 */
class Assistant:Human(),AAA(),IMoney by Person(),IWork by Person(){

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

    override fun haha() {

    }

}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

AAA()那里会报错:

Only one class may appear(出现) in a supertype list
  
  
  • 1

猜你喜欢

转载自blog.csdn.net/u013651026/article/details/80261173