Android开发,Kotlin的了解与学习(六)-----类与继承
2017-06-21 15:15
246 查看
前几章已经把kotlin最基本的语法、数据结构等说清楚了,接下来这两章主要讲解kotlin中关于类和接口的相关知识
另外需要注意的是,如果类的内部没有实体,可以直接这么写
kotlin中的构造方法和java有很大的不同,kotlin的构造方法分为两种:主构造方法、次构造方法
1.主构造方法:
constructor就是构造方法的意思,如果主构造方法中没有注解或者可见性修饰符的时候,constructor可以省略不写
同时,每个类都提供了一个初始化方法,用于在构造之后,进行初始化
如下:
另外除了在init中使用,也可以在类本身中使用
除了在类体中初始化参数,还可以在构造方法的参数前加var或者val直接进行赋值
此时就相当于已经走了初始化、赋值两个步骤
2.次构造方法:
次构造方法和java类似,是放在类里面的
如果类存在主构造方法,就必须在次构造方法后调用this方法,将方法委托给主构造方法,即如果从次构造方法中进来后,还需要再次进入主构造方法
次级构造方法可以有很多个,主构造方法只能存在一个
并且次级构造方法的this,不仅仅可以委托给主构造方法,像上面这样,也可以委托给其他的次级构造方法,只要保证最终会委托到主构造方法即可,像下面这样是不行的
两个次构造方法相互委托,会出现错误提示:There is a cycle in the delegation calls chain----委托调用链中有一个循环。
再来,我们可以看到在上面的代码中出现了三个name这参数,那么在初始化init的时候,我们调用name是指的哪一个呢?
很明显,指的是主构造方法
那么如果主构造方法没有(后面会讲到并不是没有,其实是空),我们再使用name呢
找不到name,即只有主构造方法中的参数是全局的
3.构造方法的可见性
如果像下面这样:
也相当于
默认是public的,这样我们在初始化的时候,可以这样
那么,如果我们不想让我的类被其他类构造呢,比如我只能当父类,不允许其他类跳过子类直接构造呢?
那么就可以这样写
这样,我们就不可以在其他地方构造这个类了
这一点,需要特别记住的
这样的语句,这就是类的构建了,等同于java的
注意,Kotlin中是没有new的
其他的话,其实和java就没有多大区别呢,如果构造需要参数,直接传入就可以了
kotlin的继承使用的是“:”冒号,在kotlin里面,冒号的使用是非常频繁的,继承需要、定义需要、操作需要。
如下:
这就是最简单的继承了,注意看里面的person这个类前面有一个open关键词,open在kotlin中代表了,这个类可以被继承,如果不写,其他类是无法继承该类的,这样的目的就是为了方便筛选出可继承类与不可继承类,因为在java中,如果一个类打出extends之后,会出现很多很多的类,有些类名字相似,你甚至不知道该继承哪一个,特别是在api的使用上。
然后就是复杂一点的用法:
在继承的时候,如果父类有构造方法,子类必须完整的传入构造需要的参数去进行初始化
如果一个父类存在构造方法,并且子类并没有在主构造方法中进行构造,那么就需要在次构造方法中使用super关键字,委托给父类的构造方法
同时,假如父类有多个构造方法,子类可以任意委托给其中一个
如上,fatherFoo这个方法,如果想被子类重写,就需要在前面加上open关键字,同时,子类如果要重写父类的方法,就需要在方法前加上override这个关键字,不过这个关键字倒是不需要我们自己去写,在重写时,系统会自动添加上的。
至于里面的super,我就不说了,和java一样
再一个,如果此时有一个类,继承自Man这个类,那么此时fatherFoo这个方法默认就是可以被重写的,就不需要再添加open关键字,默认就是open
那么,如果我们只想Man重写来自Person的方法,不允许Man的子类重写他父类的父类的方法,就需要在Man类的方法前加final关键字
此时,Child就不允许重写该方法了,该操作也极大的利于我们限制最外层类触及里层类的方法。
和java差不多,抽象类和抽象方法前加abstract即可
另外,子类可以使用抽象方法重写父类的一般方法
当然也不能瞎重写,父类的方法都没返回,你抽象方法也是没有返回的
最后提醒一点,抽象类,抽象方法,本来就拿给子类用的,所以,abstract修饰的方法、类,默认自带open
而这,就是kotlin无敌的人性化了。既然大家都知道这个东西的用法,我们就不再去写出来了
Android开发,Kotlin的了解与学习(七)-----接口与实现
类
类这个东西使用和java比较类似,最简单的如下class innerClass { }再class之前可以加private protected internal 或者public,默认不写就是public了
另外需要注意的是,如果类的内部没有实体,可以直接这么写
class innerClass不加括号
构造方法
提到类,肯定还会提到他的构造方法kotlin中的构造方法和java有很大的不同,kotlin的构造方法分为两种:主构造方法、次构造方法
1.主构造方法:
class InnerClass constructor(name: String) { }是的,kotlin中的主构造方法,直接就属于类名的一部分,是直接放在类名之后的
constructor就是构造方法的意思,如果主构造方法中没有注解或者可见性修饰符的时候,constructor可以省略不写
class InnerClass(name: String){ }
同时,每个类都提供了一个初始化方法,用于在构造之后,进行初始化
如下:
class InnerClass constructor(name: String) { var name: String? = null init { this.name = name } }
另外除了在init中使用,也可以在类本身中使用
class InnerClass constructor(name: String) { var myName = name }
除了在类体中初始化参数,还可以在构造方法的参数前加var或者val直接进行赋值
class InnerClass(var name: String) { init { println(name) } }
此时就相当于已经走了初始化、赋值两个步骤
2.次构造方法:
次构造方法和java类似,是放在类里面的
class InnerClass{ constructor(name: String, age: Int){ } }此时是当不存在主构造方法时的写法
如果类存在主构造方法,就必须在次构造方法后调用this方法,将方法委托给主构造方法,即如果从次构造方法中进来后,还需要再次进入主构造方法
class InnerClass(name: String) { constructor(name: String, age: Int) : this(name) { } }
次级构造方法可以有很多个,主构造方法只能存在一个
class InnerClass(name: String) { constructor(name: String, age: Int) : this(name) { } constructor(name: String, age: Int, sex: String) : this(name, age) { } }
并且次级构造方法的this,不仅仅可以委托给主构造方法,像上面这样,也可以委托给其他的次级构造方法,只要保证最终会委托到主构造方法即可,像下面这样是不行的
class InnerClass(name: String) { constructor(name: String, age: Int) : this(name, age, "") { } constructor(name: String, age: Int, sex: String) : this(name, age) { } }
两个次构造方法相互委托,会出现错误提示:There is a cycle in the delegation calls chain----委托调用链中有一个循环。
再来,我们可以看到在上面的代码中出现了三个name这参数,那么在初始化init的时候,我们调用name是指的哪一个呢?
很明显,指的是主构造方法
class InnerClass(name: String) { constructor(name: String, age: Int) : this(name) { } constructor(name: String, age: Int, sex: String) : this(name, age) { } init { println(name)//这个name指的是主构造方法中的name } }
那么如果主构造方法没有(后面会讲到并不是没有,其实是空),我们再使用name呢
class InnerClass{ constructor(name: String, age: Int) { } constructor(name: String, age: Int, sex: String) : this(name, age) { } init { println(name)//这个是会报错的,找不到name } }
找不到name,即只有主构造方法中的参数是全局的
3.构造方法的可见性
如果像下面这样:
class InnerClass { }其实,他是相当于
class InnerClass constructor(){ }
也相当于
class InnerClass public constructor(){ }
默认是public的,这样我们在初始化的时候,可以这样
var inner = InnerClass()
那么,如果我们不想让我的类被其他类构造呢,比如我只能当父类,不允许其他类跳过子类直接构造呢?
那么就可以这样写
class InnerClass private constructor(){ }
这样,我们就不可以在其他地方构造这个类了
这一点,需要特别记住的
类的构造
刚刚,我们提到了,var inner = InnerClass()这样的语句,这就是类的构建了,等同于java的
InnerClass inner = new InnerClass();
注意,Kotlin中是没有new的
其他的话,其实和java就没有多大区别呢,如果构造需要参数,直接传入就可以了
var inner = InnerClass(“name”)
类的继承
在kotlin中,类的继承和java差别还是挺大的kotlin的继承使用的是“:”冒号,在kotlin里面,冒号的使用是非常频繁的,继承需要、定义需要、操作需要。
如下:
open class Person{ } class Man : Person(){ }
这就是最简单的继承了,注意看里面的person这个类前面有一个open关键词,open在kotlin中代表了,这个类可以被继承,如果不写,其他类是无法继承该类的,这样的目的就是为了方便筛选出可继承类与不可继承类,因为在java中,如果一个类打出extends之后,会出现很多很多的类,有些类名字相似,你甚至不知道该继承哪一个,特别是在api的使用上。
然后就是复杂一点的用法:
open class Person(name: String, sex: String) { } class Man(name: String) : Person(name, "man") { }
在继承的时候,如果父类有构造方法,子类必须完整的传入构造需要的参数去进行初始化
如果一个父类存在构造方法,并且子类并没有在主构造方法中进行构造,那么就需要在次构造方法中使用super关键字,委托给父类的构造方法
open class Person { constructor(name: String) { } } class Man : Person { constructor(name: String) : super(name) { } }
同时,假如父类有多个构造方法,子类可以任意委托给其中一个
open class Person { constructor(name: String) { } constructor(name: String, age : Int){ } } class Man : Person { constructor(name: String) : super(name,0) { } }
方法的重写
子类重写父类的方法,和上面一样,也是需要在方法前加open关键字,默认修饰关键字为finalopen class Person { open fun fatherFoo(){ } } class Man : Person() { override fun fatherFoo() { super.fatherFoo() } }
如上,fatherFoo这个方法,如果想被子类重写,就需要在前面加上open关键字,同时,子类如果要重写父类的方法,就需要在方法前加上override这个关键字,不过这个关键字倒是不需要我们自己去写,在重写时,系统会自动添加上的。
至于里面的super,我就不说了,和java一样
再一个,如果此时有一个类,继承自Man这个类,那么此时fatherFoo这个方法默认就是可以被重写的,就不需要再添加open关键字,默认就是open
open class Person { open fun fatherFoo(){ } } open class Man : Person() { override fun fatherFoo() { super.fatherFoo() } } class Child : Man(){ override fun fatherFoo() { super.fatherFoo() } }
那么,如果我们只想Man重写来自Person的方法,不允许Man的子类重写他父类的父类的方法,就需要在Man类的方法前加final关键字
final override fun fatherFoo() { super.fatherFoo() }
此时,Child就不允许重写该方法了,该操作也极大的利于我们限制最外层类触及里层类的方法。
抽象类
类的抽象,如下abstract class Person { abstract fun faFoo(): String open fun getName() { println(faFoo()) } }
和java差不多,抽象类和抽象方法前加abstract即可
另外,子类可以使用抽象方法重写父类的一般方法
open class Person { open fun getName() { } } abstract class Man : Person() { abstract override fun getName() }
当然也不能瞎重写,父类的方法都没返回,你抽象方法也是没有返回的
最后提醒一点,抽象类,抽象方法,本来就拿给子类用的,所以,abstract修饰的方法、类,默认自带open
abstract class Person {//这里不需要open关键字,子类也可以继承 abstract fun getName()//这里也不需要open关键字,子类仍然可以重写 } abstract class Man : Person() { abstract override fun getName() }
而这,就是kotlin无敌的人性化了。既然大家都知道这个东西的用法,我们就不再去写出来了
Android开发,Kotlin的了解与学习(七)-----接口与实现
相关文章推荐
- Android开发,Kotlin的了解与学习(七)-----接口与实现
- Android开发,Kotlin的了解与学习(一)-----下载与安装
- Android开发,Kotlin的了解与学习(二)-----Kotlin数据类型与Extensions的学习
- Android开发,Kotlin的了解与学习(四)-----基本语法之方法、操作符
- Android开发,Kotlin的了解与学习(三)-----流程控制语句
- Android开发,Kotlin的了解与学习(五)-----基本语法之集合相关
- Android开发,Kotlin的了解与学习(九)-----在Android上的具体应用
- Android开发,Kotlin的了解与学习(八)-----kotlin与java的互相调用
- Android知识体系梳理笔记五:Kotlin学习笔记一:类和继承以及Anko(全)的基本使用
- 如果你现在学Android---学习使用Kotlin进行Android开发
- Android开发学习Kotlin
- [Kotlin&Anko开发Android入门学习笔记]-01使用Kotlin创建Activity活动
- 使用Kotlin开发android学习记录(一)
- Kotlin Android开发学习记录
- 一个实例学习Kotlin 开发 Android App 的全过程(内有代码)
- android开发艺术探索学习 之 结合Activity的生命周期了解Activity的LaunchMode
- Android开发官方语言-Kotlin学习资源汇总
- Android开发学习之四——了解项目中各文件的意义
- [Kotlin&Anko开发Android入门学习笔记]-02Kotlin如何使用Android第三方库
- 一个实例学习Kotlin 开发 Android App 的全过程(内有代码)