上一期我们讲到了加载类的顺序和延时初始化,使用lateinit关键字来注明一个需要延时初始化的成员,那么我们在用到他的时候初始化就可以了,声明就不需要赋值,一般是在使用的时候再调用该成员的初始化方法,然后在使用该成员,这是手动的,我们也学习了自动的,就是程序会自己判断该成员是否初始化,如果有就不做处理,没有就调用初始化;类加载的顺序就是先从主构造开始,然后是一气呵成的参数,在就按照我们写代码的顺序初始化类成员和init代码,其实inti和其他的成员应该是同步的;
那么这一期我们来讲一下如何继承类,匿名创建和伴生对象的认识:
1、类的继承和open关键字
kotlin的继承关键字就是:(冒号)
- //1.1 类的继承和open
- /*
- * 在kotlin中,类的继承跟Java很不一样,它使用的是:继承,
- * 而且默认状态下类的作用域为public final,不支持继承,
- * 所以我们要在类前面加上open表示剔除掉final;*/
- val p: father = son("Jerry")
- p.showresult()
- //判断类型 is as
- if(p is father){
- //改变量为father然后调用里面的函数
- (p as father).showresult()
- }
- if(p is son){
- //改变量为son然后调用里面的函数
- (p as son).showresult()
- }
继承父类的时候在:后加上父类的实现就可以了;使用open可以将作用域中的final剔除掉,让类可以继承,让方法可以重写;
- //父类
- open class father(val name: String){
- //1.2 在kotlin中所有的成员方法默认作用域也有final
- //如果一个方法有final,则不支持重写
-
- open fun getresult() = "我是父类:${name}"
- fun showresult() = println(getresult())
- }
- //子类
- class son(val subname: String): father("tony"){
- //重写了父类的方法,所有父类调用的时候也是这里的代码,这是多态性
- override fun getresult() = "我是子类:${subname}"
- }
这里我们重写了父类的一个方法,然后父类调用该方法时其实也是执行的子类的代码;
2、智能类型转换
当我们有多个子类时,通过父类接收,想要直接使用需要进行转化一下:
- //1.3 智能类型转换
- /*
- * 其实就是出现在继承中的一个步骤,当我们使用父类接收子类的时候
- * ,如果没有写as,后面的代码再用该对象调用是会报错的*/
- val p1: father = son("jhon")
- (p1 as son).showresult()
- //后面就可以直接使用p1了
- p1.showresult()
这里使用as关键字,将类型进行转化,然后后面就不在需要转了,直接可以调用,但是如果没有使用as的话,后面是会报错的;
3、超类
也就是any,相当于java中的object,其实在kotlin中所有的类都继承了这个超类,不同的是any只提供标准,不提供实现,但是object会
4、对象声明
意思就是说我们只是声明了变量,并没有实例,而且它是单例运行的,原因就是他只执行一次,就像是Java中的静态代码块,只
会执行一次
- //1.5 对象声明学习
- /*
- * 我们使用object代替之前的class就表示是一个声明类,
- * 这种类只会创建一次,也可以叫做单例类
- * */
- println(obj1)
- println(obj1)
5、对象表达式
我们可以用这个表达式来匿名实例化接口和类:
- //2.1 对象表达式的学习
- /*
- * 什么是对象表达式,就是object:父类名(){重写方法和其他}
- * 这种形式的表达式,作用就是创建一个子类,匿名的方式来
- * 重写父类里面的信息,返回值就是子类;*/
- val p2 = object : father1(){
- override fun methods1() = println("我是子类")
- }
- p2.methods1()
- //还可以实现接口
- val p3 = object : runable {
- override fun run() {
- println("我是接口")
- }
- }
- //因为都有返回值,所以kotlin很支持链式调用
格式为object:父类和重写方法,也就是一种匿名创建子类的方式:
- //对象表达式
- open class father1(){
- open fun methods1(){
- println("我是父类")
- }
- }
- //实现接口
- interface runable{
- open fun run()
- }
6、伴生对象
一个类我们可以含有一个伴生对象,后面实例化再多次伴生对象始终只有一个:
- //2.2 伴生对象的学习
- /*
- * 伴生对象是在一个类里面类,带有companion
- * 不管我们实例化多少个类,伴生对象之后一个*/
- val p4 = obj2.cmp1
- println(p4)
- //伴生对象的学习
- println(p4.vue1)
-
- class obj2(){
- val vue = "主类"
- companion object cmp1 {
- val vue1 = "伴生对象"
- fun methods1() = println("我是伴生对象")
- }
- }
伴生对象的成员可以直接点出来,不管是属性还是方法,这就跟Java中的static一样;
好了,那么这一期到这就结束了,快去试试吧,代码一定要多敲才能有质的变化。