Kotlin中那些特别的类

Kotlin中那些特别的

类(Class)是面向对象程序设计(OOP,Object0Oriented Programming)实现信息封装的基础。包含属性和方法……

以上是摘抄自百度百科的关于描述,作为Android开发者,我们接触最多的无过于Java以及现在火热的Kotlin

不同于Java中相对中规中矩的通用简一的类定义方式,在Kotlin中有了较多的关键字类定义一些特别的类,比如单例类伴生对象内部类密封类数据类等,对比于Java我们来分析一下这些特别的类,会不会让你学的特别累

一、简化的数据类

数据类(data class),用于保存元数据的封装类,Java中的POJO(Plain Ordinary Java Object)所有都是继承自Object,并自然而然的有其toString()hashcode()equals()等函数。一般都需要有getter/setter,复杂的Java Bean的话,手写getter/setter实在是挺繁琐的,即使有些快捷框架,也未必能尽如人意。

public class Student {
    private String name;
    private int age;
    private String desc;

    public Student() {
        //无参构造函数
    }

    /**
     * 多参数构造函数
     * @param name
     * @param age
     * @param desc
     */
    public Student(String name, int age, String desc) {
        this.name = name;
        this.age = age;
        this.desc = desc;
    }

    //getter/setter
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    //...其他setter getter

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", desc='" + desc + '\'' +
                '}';
    }
}

Kotlin中对应数据类data class

data class Student(val name:String,var age:Int,var desc:String)

查看kotlin转java的代码,就会感觉的kt的甜甜蜜蜜

在AS中Tools--Kotlin--ShowKotlinBytecode得到Kotlin字节码,点击Decompile得到对应的Java代码形式

数据类

数据类的知识点:

  1. 和其他Kotlin的定义类一样,都是默认final的;

  2. 可以看出Kotlinnullable可空类型是区别的,StringString?不一样。图中可见,反编译后对应Java写法就是@NotNull的注解;

  3. data class是专用的数据封装类,它的构造函数至少有一个主构造函数及至少一个入参,主构造函数的入参必须有val/var的修饰(这么才算做是类的属性而非简单的构造入参);

  4. 数据类会将构造函数内的参数依顺序生成component123之类的,便于读取,自然也根据权限修饰符来确定属性的getter/setterval的是没有setter的;

  5. 可通过默认值的形式来实现其他无参构造的需求data class AA(val name:String="")

  6. 类中声明的属性,如果data class不复写toString()equals()hashcode(),那么默认判定对象特征值只是用到构造函数内的属性参数,也就会出现即使类内属性值不一致而认定为相等,记住是相等而不是同一对象

    //name是构造属性
    data class People(val name:String){
        var age:Int = 18//类内属性
    }
    //构造参数只有name,如果一致,即使age不一致
    val p1 = People("张三")
    val p2 = People("张三")
    p1.age = 20
    p2.age = 30
    //若没有复写equals、hashcode,就会会判定为两个对象相等,
    p1== p2 就是true
    //切记!! 相等的原因是没有override equals和hashcode,但是对象本身并不是同一个,
    p1===p2 是false
    

    数据类有copy函数,不同于JavacloneKotlin中的copy就是便捷的帮你new了对象并赋值了原有对象的参数(根据你的修改与否)

     @Test
        fun testKt(){
    
            val a1 = AA("张三")
            val a2 = AA("张三")
            val a1Copy  = a1.copy()
            val a2Copy  = a2.copy(name = "李四")
            a1.age = 19
            a2.age = 29
            println("a1===a2 ${a1 === a2}")
            println("a1==a2 ${a1 == a2}")
            println("a1==aCopy ${a1 == a1Copy}")
            println("a1===a1Copy ${a1 === a1Copy}")
            println("a1==a2Copy ${a2 == a2Copy}")
            println("a1===a2Copy ${a2 === a2Copy}")
    
        }
    //输出结果
    a1===a2 false
    a1==a2 true
    a1==aCopy true
    a1===a1Copy false
    a1==a2Copy false
    a1===a2Copy false
    

    看一下对应java代码,可以看出copy就是甜甜的语法糖,帮你new

copy
  1. 数据类的解构声明

    可能不好理解这个词,看代码就清晰了

    data class AA(val name:String,var age:Int,var desc:String)
    //定义一个函数,返回AA对象
    fun getAA():AA{
        return AA("zhangsan",39,"a worker")
    }
    //调用处,就可感觉到解构声明的魅力
    val aaa = getAA()//普通的方式
    val (name,age,desc) = getAAA()//解构声明的方式,便于直接使用某些参数,而不需要aaa.name
    
  2. 系统标准库提供了PairTriple数据类,分别是两个参数和三个参数的。

  3. 封装性的数据类,可使用泛型方式定义参数类型

    //这样数据类可以使用泛型确定内部参数类型,也有其特定使用场景
    data class BBB<T,R,Q,S>(val t:T,var r:R,var q:Q,val s:S)
    
二、不是🐝甜似🍯的密封类

密封类用以表示受限的类继承结构

快速理解,类似于大号的枚举,用于特定类型限定。与枚举异同

  • 枚举,一种特定类型,可有多个枚举常量。每个枚举值只是一个实例。
  • 密封类,可有很多子类,每个子类都可有多个实例。
  1. 密封类的使用特性注意点

    • sealed关键字,其所有子类都必须在同一kt文件内,且最好是top level的;
    • 若在其他类内声明,则其子类就只能在自身内部声明了;
    • 密封类是抽象的,可有抽象成员,但不能实例化;
    • 密封类构造函数私有;
  2. 演示更直白

    class ExampleUnitTest {
        //在其它类内声明,则其子类也就只能在其内部了,根源在于sealed class的私有化构造函数
        sealed class HHH() {
            object mmm : HHH()
        }
    
        object hhhhhhh : HHH()//无法在其它类内继承 密封类
    
        data class eeeeee(val name: String) : AAAA() {
            class eee(val age: Int) : AAAA()
        }
    
    }
    
    //在外也不能继承 其他类内 看似不报错的密封类
    object ggg : ExampleUnitTest.HHH()
    
    
    //这才是合规的
    sealed class AAAA {
        fun aa() {}
        val bbb: String = ""
        open fun ad() {}
        abstract class ccc() {}
    
        //在它自身内部可以
        object jjj : AAAA()
    }
    
    data class ccc(val name: String) : AAAA() {
    }
    
    class ddd(val age: Int) : AAAA()
    object fff : AAAA()
    
    
sealed class

密封类
三、Object

Object类可以快速创建Kotlin版本的单例类,也可以是companion object的伴生对象,其特性差不多。

object单例类,也是kotlin的类的一种,比较特殊而已。

  1. 私有化构造函数,且无参数;也就是说,不能显式出构造函数,也不能有次级构造函数;
  2. 不能open/abstract,内部也不能有open的函数
  3. 其反编译为Java代码,也就是静态饿汉式的单例类写法,线程安全的。
四、枚举类

Kotlin中的枚举类,类比于Java的枚举,更为灵活一些

enum class Direction{
    NORTH,SOUTH,WEST,EAST//枚举对象用,符号分隔
}
enum class Color(val colorName:String){//这里添加val/var为的是可以称为成员属性参数
    YELLOW("#f0f0f0"), GREEN("#00f0f0"), BLUE("#000ff0");
}
  1. 类似于Java枚举,Kotlin的枚举可以有参数构造函数

  2. 不同于Java枚举,Kotlin枚举可以有抽象函数,这样每个实例都要override改函数

    enum class ColorHHH(val cn: String) {
        //每个实例,都要override
        YELLOW("#f0f0f0"){
            override fun info() {
                TODO("Not yet implemented")
            }
        }, GREEN("#00f0f0"){
            override fun info() {
                TODO("Not yet implemented")
            }
        }, BLUE("#000ff0"){
            override fun info() {
                TODO("Not yet implemented")
            }
        };
        //定义枚举类的抽象函数,其内部实例,就要override
        abstract fun info()
        open fun foo(){}
        fun boo(){}
    }
    
  3. EnumClass.valueOf(value:String)这个函数,入参是String就是对应枚举实例对象的名字。

    val co = ColorHHH.valueOf("YELLOW")//这样才能获取到
    co.name//就是实例的名字,co.ordinal,就是实例在枚举类中定义的索引编号。
    
  4. 枚举类可以实现接口,但是不能继承类。当然也不能open/abstract。同2,如果实现接口,所以实例都要实现,或者枚举类通用实现。

    interface Color9{
        fun fillColor()
    }
    interface Shape{
        fun defineShape()
    }
    //实现上面两个接口
    enum class Car:Color9,Shape{
        //1、每个实例都实现接口函数的方式
        BIZ{
            override fun fillColor() {
                TODO("Not yet implemented")
            }
    
        },BW{
            override fun fillColor() {
                TODO("Not yet implemented")
            }
        };
     //2,或者就是枚举类自身直接实现接口的函数
        override fun defineShape() {
            
        }
    }
    
五、内部类、嵌套类
  • 嵌套类,顾名思义,嵌套在其它类中的定义类。Kotlin的特别之处,接口和类可以互相嵌套,也就是类中可定义接口,接口中可定义类。

    interface OuterInterface {
        class InnerClass
        interface InnerInterface
    }
    
    class OuterClass {
        class InnerClass
        interface InnerInterface
        inner class RealInnerClass//这才是对应与Java的内部类,会引用外部类的对象
    }
    //匿名内部类,如果java的new XXX直接用一样
    window.addMouseListener(object:MouseAdapter(){
        override fun mouseClicked(e: MouseEvent){
            //...
        }
        override fun mouseEntered(e: MouseEvent){
            //...
        }
    })
    

    注意,kotlin中这么写是嵌套类,在Java中这么写就是内部类了。

  • 内部类,不同于Java中的写法,这里需要一个标记inner

  • 匿名内部类,Kotlinobject的另一作用

附:Kotlin中的类的学用知识点简略如上,更多的学习,知其然知其所以然

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,333评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,812评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,016评论 0 246
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,293评论 0 214
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,650评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,788评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,003评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,741评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,462评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,681评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,168评论 1 262
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,528评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,169评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,119评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,902评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,846评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,719评论 2 274

推荐阅读更多精彩内容