上一期我们认识了一下类的继承和创建,kotlin的继承和Java不一样,它是使用:实例化一个父类的方式,而且默认状况下类不支持继承,我们需要给父类添加一个open修饰;
1、我们来讲一个小点,就是内部类和嵌套类,顾名思义,就是一个类在另一个类里面的两种情况,那么是那两种呢?
其实就是一种通过inner关键字修饰的类叫内部类,没有关键字修饰的就是嵌套类,内部类是内外想通的,但是嵌套类却无法内外互相访问:
- //内部类:使用了inner修饰的类
- class obj3(){
- val nameouter = "我是外部类"
- //这里的obj3和obj4是互相可以访问的
- inner class obj4(){
- //内部属性访问外部
- val name2inner = "内部属性访问:${nameouter}"
- }
- }
- //嵌套类
- class obj5(){
- val name1 = "访问嵌套类"
- class obj6(){
- val name2 = "我是内部类"
- }
- }
可以看到我们的两种类,只是一个有inner修饰的区别;
- //2.3 类的嵌套和内部类
- //内部类的访问需要实例
- println(obj3().obj4().name2inner)
- //访问嵌套类只需外部类名点出来
- println(obj5.obj6().name2)
再看看它们的访问,我可以直接实例一个外部类然后点出一个内部类实例在访问内部类里面的成员,而嵌套类就不行,这可以实例一个嵌套类访问里面的成员,而外部类无法直接访问;
好了,那么这一期关于内部类和嵌套类的概念就这些,你懂了吗?
2、数据类,其实就是用来存储和处理数据的类,既然是一个类,当然也就继承自any,拥有普通类的所有方法,另外它是由data修饰,还重写和tostring,拥有copy,比较、解构等功能,我们一个一个来讲解:
我们都知道所有的类都继承自一个超类any,超类里面只提供标准,具体的实现还要看系统版本之类的,所以方法的实现结果也会不一样,但是data修饰之后,这里的很多方法都重写过了,比如tostring,普通类的tostring是一串地址,而data类的是一些类的详细信息:
- //数据类
- data class obj7(val info: String){
- fun showresult() = println(info)
- }
当创建了两个类,是同一个类的实例,如果是普通类,通过==进行比较的话会是一个false,它们内容不一样,跟版本之类的有关,但是是数据类的话就会是一样的;
数据类含有一个copy函数也挺重要的,这里就讲一下,主要就是实现一个类的克隆,但是只克隆主构造,次构造不会,因为在数据类的标准里面哪一个函数都没有执行次构造里面的成员;数据类的参数不能是临时参数,只可以是一气呵成的参数,带有val/var
- //2.5 copy函数的使用
- /*
- * 这个函数可以克隆一个主构造一模一样的对象,为什么是主构造呢?
- * 因为在主类提供的标准里面,所有的函数不会包括次构造函数的成员*/
- val p7 = obj8("Tony","copy的使用")
- println(p7)
- val p8 = p7.copy("Jerry")
- println(p8)
- //copy函数的使用
- data class obj8(var name: String){
- val str = name
- var substr: String = ""
- //次构造使用this实现主构造函数
- constructor(subname: String,info: String): this(subname){
- substr = info
- println(substr)
- }
- override fun toString() : String{
- return "str: ${str} substr:${substr}"
- }
- }
数据类的解构
什么是类的解构?就是将一个类的成员剥离出来,普通类的解构需要通过运算符重载函数来自己写解构函数,但是数据类会自动生成:
- //1.1 数据类的解构函数
- /*
- * 普通类需要写解构函数来实现一个函数将成员剥离开来的功能,
- * 但数据类自动生成了,我们可以直接用*/
- //普通类的解构
- val(name,age,sex) = obj81("Tony",18,'男')
- println("name:${name} age:${age} sex:${sex}")
- //数据类的解构
- val(name1,age1,sex1) = obj82("Jerry",17,'女')
- println("name:${name1} age:${age1} sex:${sex1}")
- //普通类的解构对象
- class obj81(name: String,age: Int,sex: Char){
- //以为传的是临时参数,所以我们需要获取到才可以用
- val name = name
- val age = age
- val sex = sex
-
- //operator是运算符重载关键字
- operator fun component1() = name
- operator fun component2() = age
- operator fun component3() = sex
- }
- //数据类的解构对象
- data class obj82(val name: String,val age: Int,val sex: Char)
自己写解构函数是有规则的,我们必须使用operator关键字,而且component1必须从1开始往后加加,不能跳过,也不能乱序,所以说kotlin对顺序要求的很严格;
运算符重载
我们可以重写一些运算符函数在数据类里面,然后我们就可以使用运算符来对类实现自己想要的加减法操作,简化代码:
- //1.2 运算符重载函数
- /*
- * 就是将运算符的功能用函数写一下,简便代码,有很多*/
- val p1 = obj82("Tony",18,'男')
- val p2 = obj82("Jerry",17,'女')
- println((p1 + p2))
- data class obj82(val name: String,val age: Int,val sex: Char){
- //加号的重载函数
- operator fun plus(p1: obj82): String{
- return "我是:${name},我的好友是:${p1.name}"
- }
- }
-
不过要注意写法,我们既然是写运算符重载函数,那必然少不了运算符重载关键字operator,然后加号的函数名是plus,有很多idea的代码提示都有,具体的功能看大家如何实现,函数的参数也是一个类,毕竟是类与类之间的操作;
最后补充一个知识点就是枚举类:
kotlin中的枚举是一个类,所以含有很多的功能,可以自己写,但是一定要注意,一个类想要实现枚举的功能,kotlin采用的方式就是:所有的枚举成员其实就是一个含有枚举类规则的类:
- enum class obj83(private var week: main.kotlin.week){
- //枚举的数据,格式要注意
- one(week("星期一")),
- two(week("星期二")),
- three(week("星期三")),
- four(week("星期四")),
- five(week("星期五")),
- six(week("星期六")),
- seven(week("星期日"));
- //展示函数
- fun show() = "今天${week.day}"
- //更新函数
- fun update(week: main.kotlin.week){
- this.week.day = week.day
- println("数据更新:${this.week}")
- }
- }
也就是说,我这里自定义的one~seven其实就是一个规则和枚举类一样的类,含有它的参数和函数;
枚举类使用enum修饰,我们可以和数据类结合起来使用,一个存储数据,一个功能使用;
- //枚举类,我们可以通过一个数据类来存放我们想要枚举的数据
- data class week(val num: String){
- var day = num
- }
- enum class obj83(private var week: main.kotlin.week){
- //枚举的数据,格式要注意
- one(week("星期一")),
- two(week("星期二")),
- three(week("星期三")),
- four(week("星期四")),
- five(week("星期五")),
- six(week("星期六")),
- secven(week("星期日"));
- //展示函数
- fun show() = "今天${week.day}"
- //更新函数
- fun update(week: main.kotlin.week){
- this.week.day = week.day
- println("数据更新:${this.week}")
- }
- }
枚举类里面的数据名自定义,但是传参的格式和枚举是一样的,一个成员以逗号结尾,最后一个以分号结束;
- //1.3 枚举类
- /*
- * 其实枚举在kotlin是通过一个类实现的,这样让其功能更加
- * 强大,我们可以在枚举类里面写我们想要实现的功能,枚举类
- * 类的每一个成员都是其本身,这是它实现枚举这个功能的核心*/
- println(obj83.five.show())
- //更新数据
- obj83.secven.update(week("星期天"))
- println(obj83.secven.show())
那么我们什么时候需要使用数据类呢?我们可以从特征入手:
好了,那么这一期就到这。