【编程语言】Kotlin快速入门 - 类与对象

类的组成

Kotlin中类的基本组成可写成以下的形式,Kotlin也是使用class关键字声明一个类的,我在此也同时加入了name和age两个字段。

class Student: Person() {
    var name = ""
    var age = 1

    fun eat() {
        println("$name is $age")
    }
}

Kotlin中类的实例化并不需要new关键字

var student = Student()
继承与构造函数
  • 主构造函数

设我们现在有一个学生类与人类,根据关系学生属于人,应该继承人,但是Kotlin与Java并不同,Kotlin中非抽象类不可实现,就像Java中加了final关键字的类一样,如果要使Student继承Person我们需要在class前使用open关键字来告诉kotlin。

open class Person {
    var age = 0
}

Java中继承使用extends关键字,但是在Kotlin中需要这样写,且Persion需要加上括号,下文讲到。

class Student: Person() {
    var name = ""
 }

Kotlin还涉及主构造函数和次构造函数的区别,主构造函数将会是你最常用的构造函数,每个类都默认有一个不带参数的构造函数,这点与Java类似,你也可以显式的指定参数,主构造函数的特点是没有函数体,直接写在类名后面即可,但你可能会想如果没有函数体我想在初始化的时候执行一些操作怎么办,这时候我们可以使用init结构体,类似于Java中的static结构体:

class Student(val name: String,val age: Int): Person() {
    init {
        println("$name is $age")
    }
}
fun main() {
    var s = Student("a",1)
}

这样我们就创建了一个Student对象

那么Person的括号到底是干什么用的?实际上那个括号主要是为了选择构造函数,在Java中子类在构造函数中需要调用父类的构造函数,这个规定在Kotlin也是一样的,只不过Kotlin是子类的主构造函数调用父类中的哪个构造函数,在继承的时候通过括号来指定,看个代码就懂了。

我们修改Person的主构造函数为以下内容:

open class Person(name: String, age: Int) {
}

此时,继承Person的子类Student开始报错了:
在这里插入图片描述

解决办法就是我们再给Student增加参数:

class Student(val name: String, val age: Int, name2: String, age2: Int): Person(name2, age2) {
    init {
        println("$name is $age")
    }
}

注意,我们在Student类的主构造函数中增加name2和age2这两个字段时,不能再将它们声明成 val,因为在主构造函数中声明成val或者var的参数将自动成为该类的字段,这就会导致和父 类中同名的name2和age2字段造成冲突。因此,这里的name2和age2参数前面我们不用加任何关键字,让它的作用域仅限定在主构造函数当中即可。

  • 次构造函数

任何一个类只能有一个主构造函数,但是可以有多个次构造函数。次构造函数也可 以用于实例化一个类,这一点和主构造函数没有什么不同,只不过它是有函数体的。

Kotlin规定,当一个类既有主构造函数又有次构造函数时,所有的次构造函数都必须调用主构造 函数(包括间接调用),这部分也不难,举个例子:

class Student(val name: String, val age: Int, name2: String, age2: Int): Person(name2, age2) {
    init {
        println("$name is $age")
    }

    constructor(name: String, age: Int): this(name, age, "name2", 2) {
        
    }

    constructor(): this("XuanRan", 18) {

    }
}

次构造函数使用constructor来声明,这里我们定义两个,从上往下数,第二个通过this调用第一个构造函数,第一个构造函数通过this调用主构造函数。

此时,这三个构造函数均能正常使用。

  • 无主有次

有时候我们会出现一种情况,无主构造函数有次构造函数,这种情况在Kotlin也是允许的,但是基本见不到,在这种情况下,我们可以省略括号的写法,并使用super关键字,这点就和Java类似了:

class Student: Person {
    constructor(name: String, age: Int): super(name, age) {

    }
}

数据类

我们有时候在Java开发中需要经常重写equals、hashCode、toString方法,但是Kotlin提供了一个修饰符能够自动的帮我们完成,那就是数据类,使用data修饰。

data class Phone(val brand: String, val price: Double)

他的效果等于Java中的

public class Phone {
    private String brand;
    private double price;

    public Phone(String brand, double price) {
        this.brand = brand;
        this.price = price;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Phone phone = (Phone) o;
        return Double.compare(phone.price, price) == 0 && Objects.equals(brand, phone.brand);
    }

    @Override
    public int hashCode() {
        return Objects.hash(brand, price);
    }

    @Override
    public String toString() {
        return "Phone{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                '}';
    }
}

单例类

在Java中单例类,我们需要通过一个静态变量来存储类对象,并且在获取实例的时候进行判断是否已初始化,如果已经初始化直接返回,否则创建新对象后返回,这种一成不变的套路在Kotlin可以直接通过一个object修饰符来完成。

object Phone {
    fun hello() {
        println("Hello!")
    }
}
fun main() {
    // 直接像调用静态方法那般调用即可
    Phone.hello()
}

密封类

在Kotlin中,假设接口类中没有方法,那么可以直接省略大括号。这里我们定义两个Result的实现类,Success与Error

interface Result
class Success(val msg : String) : Result
class Error(val error : Exception) : Result

假设我们有一个方法需要根据Result来获取返回的信息,但是由于when的语法规则中必须存在默认的else分支,我们不得不需要编写else的代码:

fun getResultMsg(result: Result) = when(result) {
    is Success -> result.msg
    is Error -> result.error.message
    else -> throw RuntimeException()
}

并且最重要是,假设以后Result多了更多的实现,我们可能会忘记在方法中添加其他的实现造成抛出异常,给他而密封类就可以很好的解决这个问题,密封类的关键词是sealed class,我们修改Result的代码:

sealed class Result
class Success(val msg : String) : Result()
class Error(val error : Exception) : Result()

由于密封类是可以被继承的,所以在继承时需要加一个括号,然后我们修改getResultMsg的方法时就发现else是可以忽略的:

fun getResultMsg(result: Result) = when(result) {
    is Success -> result.msg
    is Error -> result.error.message
}

并且假设Result类增加了新的继承,when这里会报错提示我们必须要考虑到新的情况。

类型强转

在Java中,我们可以通过(转换类型)来实现类型的强制转换,但是在Kotlin中,我们就需要使用as关键字进行类型转换:

// 将student这个变量强转成Study
var s : Study = student as Study

接口

与Java一致,Kotlin的接口也是使用interface修饰,与Java不同的是Kotlin支持默认实现,而Java自JDK1.8之后才支持默认实现。

interface Study {
    fun doHomeWork()

    fun doReadBook() {
        println("read book.")
    }
}

接口的实现在Java中是implements,在Kotlin中则是冒号,然后多实现使用逗号隔开。

class Student(name: String, age: Int, val clazz: String): Person(name, age), Study {
    override fun doHomeWork() {
        println("do homework.")
    }
}

我们在此节补充一下Java和Kotlin中可见性修饰符。

修饰符JavaKotlin
public所有类可见所有类可见(默认)
private当前类可见当前类可见
protected当前类、子类、同一包路径下的类可见当前类、子类可见
default同一包路径下的类可见(默认)
internal同一模块中的类可见

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WebGL编程指南 - 入门续

相关内容:在attribute变量传递参数的基础上,通过JavaScript获取鼠标事件的坐标,再经过坐标转换传递给attribute变量;Web颜色缓冲区每次绘制之后都会重置相关函数:JavaScript鼠标事件onmousedown/onmouseup/onclick htm…

0基础学java之Day09(下午完整版)

六、数组 概念: 1.数组是引用数据类型 2.数组中的数据叫做元素 3.元素都有标号叫做索引/下标 4.下标从0开始 5.数组一旦初始化成功,长度不可变(意味着数组没有添加和删除) 6.数组中的元素在内存中是挨在一起的 声明: 数…

数据结构与算法 - 树 #数的概念 #二叉树 #堆 - 堆的实现/堆排序/TOP-K问题

文章目录 前言 一、树 (一)、概念 1、树的定义 (二)、树的定义 1、树为什么是递归定义的? 2、如何定义树(如何表达一棵树) 解决方案一:假设我们得知该树的度 解决方案二:顺序表 解决方案三:左孩子右兄弟表示法 二、二叉…

人工智能是否会取代人类的工作吗? 就业方向该如何抉择

人工智能是否会取代人类的工作一直是备受关注的话题。目前来看,人工智能在某些方面确实展现出了强大的能力,但要说完全取代人类还不太可能。 一、人工智能的优势 高效处理大量数据 人工智能可以快速处理和分析海量数据,例如在金融领域进行风…

linux------缓冲区与C库的原理

前言 一、缓冲区 缓冲区的作用是提高效率,因为将数据写入到设备,是需要调用系统接口的,如果每次写入缓冲区的数据就调用一次系统调用,涉及到系统调用这时操作系统就会介入,用户态转为内核态,这个过程需要时…

解决PyCharm 2023 Python Packages列表为空

原因是因为没有设置镜像源 展开 > 之后,这里 点击齿轮 添加一个阿里云的源 最后还需要点击刷新 可以选择下面的任意一个国内镜像源: 清华:https://pypi.tuna.tsinghua.edu.cn/simple 阿里云:http://mirrors.aliyun.com/…

Vue3 集成Monaco Editor编辑器

Vue3 集成Monaco Editor编辑器 1. 安装依赖2. 使用3. 效果 Monaco Editor (官方链接 https://microsoft.github.io/monaco-editor/)是一个由微软开发的功能强大的在线代码编辑器,被广泛应用于各种 Web 开发场景中。以下是对 Monaco Editor 的…

微深节能 料场堆取料无人操作系统 格雷母线

微深节能的料场堆取料无人操作系统采用了格雷母线定位系统,这是一种高精度位移检测技术,用于提升料场作业的自动化水平和精确性。该系统通过精准定位和自动化控制,大幅减少了人工操作中的误差和延误,提高了作业效率和精确性。格雷…

Jenkins入门(二):流水线方式部署多模块Springboot项目

目录 一、环境准备 1. 搭建配置Jenkins (在上一篇基础上进行) 2. 安装mysql 3. 安装redis 4. 配置docker-componse 5. 启动docker-componse 二、脚本准备 1. Jenkinsfile 2. deploy.sh 3. Dockerfile 三、Jenkins流水线配置 新增版本号参数 流水线选择代码里面的Je…

Python酷库之旅-第三方库Pandas(158)

目录 一、用法精讲 721、pandas.Timedelta.round方法 721-1、语法 721-2、参数 721-3、功能 721-4、返回值 721-5、说明 721-6、用法 721-6-1、数据准备 721-6-2、代码示例 721-6-3、结果输出 722、pandas.Timedelta.to_pytimedelta方法 722-1、语法 722-2、参数…

农作物苹果叶片病虫害识别数据集

农作物苹果叶片病虫害识别数据集 一、引言 农作物病虫害是影响农业生产的重要因素之一,其中苹果作为广泛种植的水果品种,其叶片病虫害问题尤为突出。为了有效应对苹果叶片病虫害,提高苹果产量和品质,农业科研机构和学者不断开展…

服务端负载均衡和客户端负载

负载均衡分为服务端负载均衡和客户端负载均衡,图解: 客户端的负载均衡还需要从注册中心获取集群部署的服务地址,其中客户的负载均衡器定时读取注册中心的IP和端口,然后缓存起来,这样以后可以先判断缓存IP和端口是否可用…

Java基于SSM微信小程序物流仓库管理系统设计与实现(源码+lw+数据库+讲解等)

选题背景 随着社会的发展,社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景,运用软件工程原理和开发方法,它主要是采用java语言技术和mysql数据库来完成对系统的设计。整个…

#数据结构(二)

栈和队列 一.栈的顺序存储结构 特点:先进后出 栈是一种只能在一端进行插入或删除操作的线性表。 表中允许插入删除操作的一端为栈顶(top),表的另一端为栈底(bottom), 1 结构体的定义 #incl…

10月18日

二次型矩阵要是对称矩阵 通解要带入特解 集体化 逆反思维 先定特解,再求通解 反函数...我谢谢你 依旧是原函数

Vision China 2024 | 移远通信以一体化的AI训练及部署能力,引领3C电子制造智能升级

10月14日,由机器视觉产业联盟(CMVU)主办的中国机器视觉展(Vision China)在深圳国际会展中心盛大开幕。作为全球领先的物联网整体解决方案供应商,移远通信应邀参加展会首日举办的“智造引领数质并进”3C电子制造自动化与数字化论坛。 论坛上,移…

立仪科技:光谱共焦传感器精准测量玻璃

光谱共焦测量技术作为一种创新的光学检测方法,近年来在工业领域引起了广泛关注。 它以其高精度、非接触式的特点,特别适用于透明或半透明材料如玻璃的厚度和表面形貌测量。 接下来,立仪科技小编将深入探讨光谱共焦技术在玻璃测量上的应用及其…

火山引擎数智平台 VeDI:A/B 实验互斥域流量分配体系上线

近日,火山引擎 A/B 测试平台(DataTester)完成了一次重要升级,推出互斥域流量分配体系,这一功能意味着企业在产品优化策略上有新的突破空间。此次升级的核心亮点是允许企业根据实际需求,灵活地将用户流量分割成多个独立的区块&…

探索 Jupyter 笔记本转换的无限可能:nbconvert 库的神秘面纱

文章目录 探索 Jupyter 笔记本转换的无限可能:nbconvert 库的神秘面纱背景:为何选择 nbconvert?库简介:nbconvert 是什么?安装指南:如何安装 nbconvert?函数用法:简单函数示例应用场…

简单概述Ton链开发路径

区块链开发领域发展迅速,各种平台为开发人员提供不同的生态系统。其中一个更有趣且越来越相关的区块链是TON(开放网络)区块链。TON 区块链最初由 Telegram 构思,旨在提供快速、安全且可扩展的去中心化应用程序 (dApp)。凭借其独特…