Kotlin语法入门-类与对象(6)

news2024/10/5 14:03:49

Kotlin语法入门-类与对象(6)

文章目录

  • Kotlin语法入门-类与对象(6)
    • 六、类与对象
      • 1、声明和调用
      • 2、get和set
      • 3、init函数初始化
      • 4、constructor构造函数
        • 4.1、主构造函数
        • 4.2、二级构造函数
        • 4.3、多个构造函数
        • 4.4、省略主构造函数并写了次构造函数
      • 5、类的继承与重写
        • 5.1、继承
        • 5.2、继承构造函数初始化
        • 5.3、函数的重写
        • 5.4、属性的重写
      • 6、抽象类、嵌套类和内部类
        • 6.1、抽象类
        • 6.2、嵌套类
        • 6.3、内部类

六、类与对象

1、声明和调用

fun main() {
    var a = A()  // 面相函数式,所以不用new关键字也可以
    a.print()
}

class A {
    val a = 2
    fun print() {
        println(a)
    }
}

2、get和set

在kotlin中,不能直接调用get和set方法,默认就是赋值就自动调用了set()方法,取值就自动调用get()方法。

就像下面这段示例,test.a = 5这个赋值操作调用set(),取值调用get():

fun main() {
    var test = A()
    test.a = 5
    test.print()

}

class A {
    var a = 2
        get() {
            return field - 1
        }
        set(value) {
            field = value + 1
        }
    fun print() {
        println(a)
    }
}

输出结果:

image-20240418153123854

3、init函数初始化

我们可以在类中添加初始化函数,每当创建一个类的对象之后,init方法就会自动调用,可以用于初始化数据

fun main() {
    var test = A()
}

class A {
    var a = 2
    init {
        println("A") //自动调用
    }
}

通过传入值初始化:

fun main() {
    var test = A(5)
}

class A(b: Int) {
    var a = 2

    init {
        a = b
    }
}

值得注意的是:在对对象传入值的之后可以同时对变量初始化,例如:class A(var b: Int) {},就代表了b就成为了A对象的成员变量,kotlin语法支持这样写。

但是只能在一级构造函数(主构造函数)上写这种,在二级构造函数中不支持这种语法,二级构造函数接下来有介绍。

4、constructor构造函数

在kotlin中奖构造函数分为主构造函数次构造函数

4.1、主构造函数
class  A constructor() {
    var a = 2
    init {
     	// 主构造函数的方法体
    }
}

其中,主构造函数关键字constructor可以省略不写,其构造的方法体就在init函数中。

4.2、二级构造函数
class A constructor(var b: Int = 1) {
    var a = 2

    init {
        println("init()...")
    }

    constructor() : this(3) { //代理主构造函数
        println("次构造函数...")
    }
}

注意:次构造函数需要主构造函数调用才能实现,即使用this()代理主构造函数,也可以传入参数this(3),可就是将b赋值为3。

这种方式就相当于java中的在构造方法中调用其他构造方法。

4.3、多个构造函数
class A constructor(var b: Int = 1) {
    var a = 2

    init {
        println("init()...")
    }

    constructor(c: Int, d: Int) : this(3) {
        println("次构造函数1...")
    }

    constructor() : this(1, 2) {
        println("次构造函数2...")
    }
}

image-20240418161321029

当然,次构2不一定要代理次构1,也可以直接代理主构,但是次构1就失效了。

4.4、省略主构造函数并写了次构造函数

例如这种,就直接成为主构造函数了:

class A  {
    constructor(c: Int, d: Int) {
        //此时识别为主构造函数
    }
}

多态

class A  {
    constructor(c: Int, d: Int) {
       
    }
    constructor(c: Int) {
        
    }
}

5、类的继承与重写

5.1、继承
fun main() {
    var b = B()
    b.print()
}

open class A {  //一定一定要添加open关键字
    var a = 1
}

class B : A() {
    var b = 2
    fun print() {
        println(a)
        println(b)
    }
}

一定一定要添加open关键字。

5.2、继承构造函数初始化

子类继承父类,子类要对父类进行构造方法的初始化:

1、主构造函数初始化

open class AParent {

}

class AChild() : AParent() {

} 

2、次构造函数初始化

open class AParent {

}

class AChild : AParent {
    constructor() : super(){}
}

3、父类多构造函数–子类主构造函数调用

当父类函数存在两个构造函数时,分别为主构造函数二级构造函数

open class AParent(name: String, age: Int) {
    constructor(name: String) : this(name, 30)
}

子类函数2:

class AChild() : AParent( "A") {}

子类函数1:

class AChild() : AParent( "A",15) {}

上述两种方式都可以实现父类构造函数的初始化,图解:

image-20240418172945118

3、父类多构造函数–子类副构造函数调用

image-20240418173640550

赋值输出:

fun main() {
    var aChild = AChild("rediaz")
    aChild.print()
}

open class AParent(var name: String, var age: Int) {
    constructor(name: String) : this(name, 30)
}

class AChild : AParent {
    constructor(name: String) : super(name)
    fun print(){
        println("name: ${super.name}")
    }
}

image-20240418174040391

5.3、函数的重写

正常继承,默认无法进行重写:

image-20240418174447191

它说需要override关键字,好嘛加上:

image-20240418174609562

然后又说基类的方法关键字是final修饰的。

正确重写方式,在父类的成员方法中加上open关键字:

open class AParent() {
    open  fun A() { println("A") }
    open fun B() { println("B") }
}

class AChild : AParent() {
    override fun A() {}
    override fun B() {}
}
5.4、属性的重写

这个是kotlin中特有的操作,Java中没有。

示例:

open class AParent() {
    open val a = 1
   open var b = 2
}

class AChild : AParent() {
    override val a: Int
        get() = super.a

    override var b: Int
        get() = super.b
        set(value) {}
}

上述这种方式就实现了重写属性成员a和b,其中a是常量,b是变量,所以重写之后有点区别。

重写的时候可以直接赋值进行覆盖:

open class AParent() {
    open val a = 1
    open var b = 2
}

class AChild : AParent() {
    override val a: Int = 0
    override var b: Int = 0
}

但是底层还是有get和set方法

重写时将a的val换成var,则其会将代码编译成新的变量,并生成对应的get和set方法:

image-20240418180434262

6、抽象类、嵌套类和内部类

6.1、抽象类

对于抽象类,其用法与Java无异

抽象是面向对象编程的特征之一,类本身,或类中的部分成员,都可以声明为abstract的。抽象成员在类中不存在具体的实现。

需要注意的是:不用对抽象类或抽象成员标注open注解。

abstract class AParent() { // 抽象类
    abstract fun sum() // 抽象方法
}

class AChild : AParent() {
    override fun sum() {
       
    }
}
6.2、嵌套类

先上代码:

fun main() {
    var aParent = AParent()
    aParent.print()
    var aChild = AParent.AChild()
    aChild.print()
}

class AParent() { // 抽象类
    fun print() {
        println("外部类")
    }

    class AChild() {
        fun print() {
            println("嵌套类")
        }
    }

}

注:在Java中,这是一个内部类的一个写法,但是在koltin中,这种事属于内部类的一个写法。

嵌套类是被final关键字修饰的

6.3、内部类

在嵌套类的基础上,在嵌套类的前面加上一个关键字inner就变成了内部类,并且可以访问外部类中的成员变量,使用this@类名的方式。示例:

fun main() {
    AParent().AChild().print()
}

class AParent() {
    val a = 1
    fun print() {
        println("外部类")
    }
 
    inner class AChild() { //加上inner关键字
        fun print() {
            println("嵌套类")
            println(this@AParent.a) //获取AParent中的a值
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1617767.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Tello无人机】无人机编队操作面板实现

为了方便进行无人机的编队演示,以及在各种场景下实现队形的灵活切换,开发了一套专门的上位机控制平台。本文将重点介绍应用于tello无人机的编队操作面板及其核心功能。 操作面板页面 下图展示了操作面板,其中包含5种编队动作和3个可选位置设…

2024深圳杯(东北三省)数学建模选题建议及各题思路来啦!

大家好呀,2024深圳杯数学建模(东北三省数学建模联赛)开始了,来说一下初步的选题建议吧: 首先定下主基调, 本次深圳杯(东北三省)建议选A。难度上D>B>C&#…

开源模型应用落地-chatglm3-6b-集成langchain(十)

一、前言 langchain框架调用本地模型,使得用户可以直接提出问题或发送指令,而无需担心具体的步骤或流程。通过LangChain和chatglm3-6b模型的整合,可以更好地处理对话,提供更智能、更准确的响应,从而提高对话系统的性能…

Linux中进程和计划任务管理(2)

一.进程命令 1.lsof lsof 命令,“list opened files”的缩写,直译过来,就是列举系统中已经被打开的文件。通过 lsof 命令,我们就可以根据文件找到对应的进程信息,也可以根据进程信息找到进程打开的文件。 格式&…

【详细实现】v1.0 随机点名应用

1.引言 前面对这个应用的功能做了详细的分析(长什么样、能干什么),以先这样对一个项目最开始的分析成为需求分析,需求分析之后就是设计阶段。 那么一般的项目,在设计阶段都需要干什么呢?在需求分析阶段确定…

Linux系统中安装MySQL

1、在电脑中安装虚拟机 2、df -h查看光盘是否挂载,没挂载用mount -o ro /dev/sr0 /media命令挂载 3、进入etc/yum.repos.d目录查看仓是否配置,若配置进行下一一步,未配置则进行配置 配置软件仓库 [rootlocalhost yum.repos.d]# vim rhle.r…

423 世界读书日 和京东零售技术人一起读好书

我们正处于一个复杂、变化的世界,想要更好地理解、适应它,读书可能是最方便的方式之一。 4 月 23 日世界读书日,我们整理了 10 位零售技术人的书籍推荐给大家,欢迎大家一起来共读好书。愿大家在忙碌工作之余,都能够持…

Kubectl常见排查pod问题命令

一.查看命名空间pod及其日志 #查看命名空间pod kubectl get pods -n <命名空间名称> #该命令不加-n命名空间名称&#xff0c;默认是查看default命名空间的pod#查看对应pod的日志kubectl logs -f <pod-name> -n <namespace>#同样的如果查看的是default命名空…

在 vue3 中使用高德地图

前言&#xff1a;定位地图位置所需要的经纬度&#xff0c;可以通过 拾取坐标 获取。 一&#xff1a;快速上手 1. 安装依赖 npm install amap/amap-jsapi-loader # or pnpm add amap/amap-jsapi-loader # or yarn add amap/amap-jsapi-loader 2. 创建组件 src/components/Ma…

有关栈的练习

栈练习1 给定一个栈&#xff08;初始为空&#xff0c;元素类型为整数&#xff0c;且小于等于 109&#xff09;&#xff0c;只有两个操作&#xff1a;入栈和出栈。先给出这些操作&#xff0c;请输出最终栈的栈顶元素。 操作解释&#xff1a; 1 表示将一个数据元素入栈&#xff…

Mysql 存在多条数据,按时间取最新的那一组数据

1、数据如下&#xff0c;获取每个用户最近的一次登录数据 思路1&#xff1a;order by group by 先根据UserIdLogInTime排序&#xff0c;再利用Group分组&#xff0c;即可得到每个User_Id的最新数据。 1 SELECT * FROM login_db l ORDER BY l.user_id, l.login_time DESC; 排…

一款辅助应用助力盲人公交出行畅行无阻

在这个日新月异的时代&#xff0c;科技进步正以前所未有的速度改变着人们的生活方式&#xff0c;尤其是在提升特殊群体生活质量方面展现出巨大潜力。今日&#xff0c;我们将目光聚焦于盲人公交出行&#xff0c;探讨一款名叫蝙蝠避障的创新辅助应用如何以其实时避障与拍照识别功…

vben admin Table 实现表格列宽自由拖拽

更改BasicTable.vue文件 Table添加 resize-column“resizeColumn” 添加并 return resizeColumn const resizeColumn (w, col) > { setCacheColumnsByField(col.dataIndex, { width: w }); }; 在column中添加 resizable: true,

做一个答题pk小程序多少钱

在探讨“做一个答题pk小程序多少钱”这一问题时&#xff0c;我们首先需要明确的是&#xff0c;小程序的价格并非固定不变&#xff0c;而是受到多种因素的影响。这些因素包括但不限于小程序的复杂度、功能需求、开发周期、技术难度以及开发团队的规模和经验等。因此&#xff0c;…

单机单实例部署RocketMQ及测试

部署Apache RocketMQ需要准备NameServer、Broker、Proxy三个组件。它有几种部署模式&#xff1a; Local模式:Broker 和 Proxy 是同进程部署Cluster模式:Broker 和 Proxy 分别部署 为了部署简便&#xff0c;我们采用local模式。 RocketMQ部署 Dockerfile FROM ubuntu:22.04 …

Linux KASAN使用与实现原理

一、KASAN工具使用 KASAN工具&#xff1a;Kernel Address SANitizer(KASAN)是一种动态内存安全错误检测工具&#xff0c;主要功能是检查内存越界访问和使用已释放内存的问题。 1.1 KASAN宏控开关 KASAN有三种模式&#xff1a;1.通用KASAN&#xff1b;2.基于软件标签的KASAN&…

模版初阶【C++】

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ &#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1…

嵌入式Python基础1-2

嵌入式Python基础1-2 条件语句 if elif else 随机数random eval while循环 for循环 水仙花数 循环else list 列表常用方法 增删改查 加排序 append remove pop index() 升序sort(&#xff09;降序 sort(reverseTrue) 反转 reverse&#xff08;&#xff09;…

[Collection与数据结构] PriorityQueue与堆

1. 优先级队列 1.1 概念 前面介绍过队列&#xff0c;队列是一种先进先出(FIFO)的数据结构&#xff0c;但有些情况下&#xff0c;操作的数据可能带有优先级&#xff0c;一般出队列时&#xff0c;可能需要优先级高的元素先出队列&#xff0c;该中场景下&#xff0c;使用队列显然…

持续更新。。。

1、JAVA面试指南 https://javaguide.cn/ 简历优化&#xff1a;突出与应聘职位相关的项目经验、技术栈、技能证书和专业成就。确保简历中的技术关键词与JD&#xff08;Job Description&#xff09;相符。 自我评估&#xff1a;对照目标职位要求&#xff0c;梳理自身Java技能树&…