Kotlin中级(9)- - - Kotlin类之数据类、密封类、内部类.md

数据类

1.声明

data关键字

data class Leaf(val size: String,val color: String,val shape: String,val vein: Int)

2.数据类声明条件

  1. 主构造函数最少要有一个参数
  2. 数据类的主构造器的所有参数必须标记为val或var
  3. 数据类不能是抽象类、open类、封闭类、内部类
  4. 数据类不能继承自任何其他类(但可以实现接口)

3.访问数据类的2种方法

  1. 和普通类一样"对象名.数据名"
  2. 编译器从主构造函数中声明的属性中导出的成员方法componentN()函数群
data class Leaf(val size: String,val color: String,val shape: String,val vein: Int)

fun main(args: Array<String>) {
    val leaf = Leaf("20","green","cicle",57)
    val size = leaf.size
    val color = leaf.color
    val shape = leaf.shape
    val vein = leaf.vein
    println("大小:$size 颜色: $color 形状 $shape 叶子数: $vein")
}
data class Leaf(val size: String,val color: String,val shape: String,val vein: Int)

fun main(args: Array<String>) {
    val leaf = Leaf("20","green","cicle",57)
    val(size,color,shape,vein) = leaf
    println("大小:$size 颜色: $color 形状 $shape 叶子数: $vein")
}

4.componentN()函数群

componentN函数群会按声明顺序对应于所有属性

上面的代码我们可以看到结构出来的变脸可以直接拿来用,比如数据体Leaf中的size属性,componentN函数群会按照数据体Leaf中属性声明的顺序,从component1到component4和size、color、shape、及vein一一对应。

5.编辑器做的事

  1. 生成equals()函数与hasCode()函数
  2. 生成toString()函数,由类名(参数1 = 值1,参数2 = 值2,…)构成
  3. 由所定义的属性自动生成component1()、component2()、…、componentN()函数,其对应于属性的声明顺序。
  4. copy()函数。(Koltin要修改数据类的属性,则使用其独有的copy()函数。其作用就是:修改部分属性,但是保持其他不变)

密封类

1. 什么是受限的类继承结构

  1. 所谓受限的类继承结构,即当类中的一个值只能是有限的几种类型,而不能是其他的任何类型。
  2. 这种受限的类继承结构从某种意义上讲,它相当于是枚举类的扩展。但是,我们知道Kotlin的枚举类中的枚举常量是受限的,因为每一个枚举常量只能存在一个实例
  3. 但是其和枚举类不同的地方在于,密封类的一个子类可以有可包含状态的多个实例。
  4. 也可以说成,密封类是包含了一组受限的类集合,因为里面的类都是继承自这个密封类的。但是其和其他继承类(open)的区别在,密封类可以不被此文件外被继承,有效保护代码。但是,其密封类的子类的扩展是是可以在程序中任何位置的,即可以不在同一文件下

2.声明

sealed class SealedExpr()

内部类(嵌套类)

在实际开发中,用到内部类的地方是很多的。比如说:

  • 对于Android开发来说,列表适配器中的ViewHolder类就是一个内部类
  • 根据后台开发人员提供的json字符串生成的对象中,也包含另外一个对象,这也是一个内部类

1.嵌套类

上面提到的两种情况,是在开发中最常见的。当然说到内部类,就必须提到另一个概念,嵌套类,所谓嵌套类:即指一个类可以嵌套在其他类中。

例如:

class Other{           // 外部类
    val numOuther = 1

    class Nested {      // 嵌套类
        fun init(){
            println("执行了init方法")
        }
    }
}

fun main(args: Array<String>) {
    Other.Nested().init()      // 调用格式为:外部类.嵌套类().嵌套类方法/属性
}

注意

  • 调用嵌套类的属性或者方法格式为: 外部类.嵌套类().嵌套类方法/属性。在调用的时候嵌套类是需要实例化的。
  • 嵌套类不能使用外部类的属性和成员

2.内部类

声明一个内部类使用inner关键字。 声明格式:inner class 类名(参数){}

class Other{            // 外部类
    val numOther = 1

    inner class InnerClass{     // 嵌套内部类
        val name = "InnerClass"
        fun init(){
            println("我是内部类")
        }
    }
}

fun main(args: Array<String>) {
   Other().InnerClass().init()  // 调用格式为:外部类().内部类().内部类方法/属性
}

*注意

  • 调用内部类的属性或方法的格式为:外部类().内部类().内部类方法/属性。在调用的时候嵌套类是需要实例化的。
  • 内部类不能使用外部类的属性和成员

匿名内部类

作为一名Android开发者,对匿名内部类都不陌生,因为在开发中,匿名内部类随处可见。比如说Button的OnClickListener,ListView的单击、长按事件等都用到了匿名内部类。 一般的使用方式为定义一个接口,在接口中定义一个方法。

class Other{
    
    lateinit private var listener : OnClickListener

    fun setOnClickListener(listener: OnClickListener){
        this.listener = listener
    }
    
    fun testListener(){
        listener.onItemClick("我是匿名内部类的测试方法")
    }
}    

interface OnClickListener{
    fun onItemClick(str : String)
}

fun main(args: Array<String>){
    // 测试匿名内部类
    val other = Other()
    other.setOnClickListener(object : OnClickListener{
        override fun onItemClick(str: String) {
            // todo
            println(str)
        }
    })
    other.testListener()
}

内部类和继承的区别

  • 从声明类上看,继承的两个类单独声明,子类通过(子类:父类)继承父类,而内部类必须声明在外部类里面,并且用关键字inner标记
  • 从访问上看,继承的父类不能直接访问子类,外部类可以通过“外部类().内部类()”访问内部类,继承的子类能直接访问父类公开的成员属性及方法,而内部类值能通过this@外部类的方式访问外部类的属性和方法
  • 从能否覆盖上看,继承的子类能覆盖父类用open标记的属性和方法,内部类不能覆盖外部类的属性和方法
  • 从定义对象的方法看,继承的子类定义为val/var son = Son(),内部类的定义为 val/var inter = Outer().Inter()

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏闻道于事

Java之面向对象概述,类,构造方法,static,主方法,对象

一、面向对象概述 面向过程 “面向过程”(Procedure Oriented)是一种以过程为中心的编程思想。这些都是以什么正在发生为主要目标进行编程,不同于...

3355
来自专栏lulianqi

支持各种特殊字符的 CSV 解析类 (.net 实现)(C#读写CSV文件)

csv(Comma Separated Values)逗号分隔值,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本...

1532
来自专栏Spark学习技巧

Java反射机制深入详解

一.概念   反射就是把Java的各种成分映射成相应的Java类。   Class类的构造方法是private,由JVM创建。   反射是java语言的一个特性...

1.7K7
来自专栏从零开始学自动化测试

python笔记2-冒泡排序

前言 面试的时候经常有面试官喜欢问如何进行冒泡排序?这个问题相信能难倒一批英雄好汉,本篇就详细讲解如何用python进行冒泡排序。 一、基本原理 1.概念: 冒...

3716
来自专栏我和PYTHON有个约会

32.企业级开发进阶4:正则表达式

本节内容,要讲解的和我们的信息检索有关系,这一方面也是Python在目前非常流行的一个应用方向:爬虫。

1011
来自专栏Java与Android技术栈

高阶函数和Java的Lambda

java 8引入了函数式编程。函数式编程重点在函数,函数变成了Java世界里的一等公民,函数和其他值一样,可以到处被定义,可以作为参数传入另一个函数,也可以作为...

1873
来自专栏微信公众号:Java团长

Java反射机制深入详解

  反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作。例如它允许一个java的类获取他所有的成员变量和...

581
来自专栏转载gongluck的CSDN博客

python笔记:#008#变量的命名

变量的命名 目标 标识符和关键字 变量的命名规则 0.1 标识符和关键字 1.1 标识符 标示符就是程序员定义的 变量名、函数名 名字 需要有 见名知义 的...

3714
来自专栏xingoo, 一个梦想做发明家的程序员

【面试虐菜】—— JAVA面试题(1)

今天参加笔试,里面有设计模式,和一些基础题! 印象最深的是:什么不是Object的函数,我蒙的finalize,哎,无知! 还问了,接口与抽象类的不同,还...

2079
来自专栏Android干货园

Kotlin中级(8)- - - Kotlin类之接口、枚举.md

742

扫码关注云+社区

领取腾讯云代金券