Kotlin快速入门系列4

Kotlin的类与对象

类的定义

Kotlin使用关键字class来声明类。后面紧跟类名字:

class LearnKotlin { //类名:LearnKotlin
    //...
}

Kotlin的类可以包含:构造函数和初始化代码块、函数、属性、内部类、对象声明。当然,也可以定义一个空类。

class Empty

类的属性

属性定义

类的属性可用var声明为可变的,否则使用关键字val声明为不可变。

class LearnKotlin {
    var IDE : String = "..."
    var practiceTime : Int = 0
    var studyReason : String = "..."
}

Kotlin没有new关键字,但我们可以像使用普通函数那样使用构造函数创建类实例:

class KotlinPractice {
    val lkt = LearnKotlin()
}

要调用或者改变其中一个属性,只需要名称引用它即可:

lkt.IDE       //使用 . 号来引用
lkt.practiceTime

当我们需要知道一个密闭的类所有属性时,可以采用反射的方式获取:

var lkt = LearnKotlin()
lkt.javaClass.getDeclaredFields().forEach { field -> println(field.name) }

Kotlin中的类可以有一个主构造方法,以及一个或者多个次构造方法。主构造方法是类头部的一部分,位于类名称之后:

class Person constructor(name: String){}

如果主构造方法没有任何注解,也没有任何修饰符,那么constructor关键字可以省略。

class Person (name: String){}

gettersetter

kotlin中,getter和setter是可选的,如果你没有在代码中创建它们,它是会默认自动生成。如上述代码:

class LearnKotlin {
    var IDE : String = "..."
    var practiceTime : Int = 0
    var studyReason : String = "..."
}

相当于:

class LearnKotlin {
    var IDE : String = "..."
    var practiceTime : Int = 0
    var studyReason : String = "..."
    set(value) {
        field = value
    }
    get() = field
}

Kotlin 中类不能有字段。提供了后端变量(Backing Fields)机制,备用字段使用field关键字声明,field关键词只能用于属性的访问器,如以上实例:

需要注意的是:

1、field关键字代表的是当前域(是不是想起了Java中的this?)。

2、val不允许设置setter函数,因为它是只读的。

下面的变量声明示例和IDE提示可以看出var和val在声明上的差别:

主构造函数方法 

java中没有主次构造函数(方法)之分,但是kotlin有。且一个kotlin类可以有一个主构造函数和多个次构造函数。

主构造函数(方法)中一般不包含任何代码,初始化代码可以放在初始化代码段中,初始化代码段使用 init 关键字作为前缀。

class KotlinPractice constructor(fileName : String){
    init {
        println("FileName is $fileName")
    }
}

主构造函数的参数可以在初始化代码段中使用。

次构造函数方法

也叫二级构造函数(方法),申明前缀有constructor修饰:

class KotlinPractice {
    //次构造函数
    constructor (fileName: String) {
        // 初始化...
    }
}

如果类中有一个主构造函数,每个次构造函数需要委托给主构造函数,可以直接委托或者通过别的构造函数。

class KotlinPractice constructor(fileName : String){
    constructor (fileName: String, fileSize: Int) : this(fileName) {
        // 初始化...
    }
}

如果一个非抽象类没有声明构造函数(主或次构造函数),它会产生一个没有参数的构造函数。构造函数是 public 。如果你不想你的类有公共的构造函数,你就得声明一个空的主构造函数:

class DoNotCreateMe private constructor () {
}

(在 JVM 虚拟机中,如果主构造函数的所有参数都有默认值,编译器会生成一个附加的无参的构造函数,这个构造函数会直接使用默认值。)

数据类

在kotlin中声明数据类极其简单,只需要使用data这个关键字在类前面声明即可。

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

当在一个类前面声明data关键字时,就表明你希望这个类是一个数据类,kotlin会根据主构造函数里的参数将equals()、hashCode()、toString()等固定且没有实际逻辑意义的方法自动生成。此外,当一个类中没有任何代码时,还可以将尾部的大括号省略。

抽象类

与Java一样,通过abstract关键字声明。抽象成员在类中不存在具体的实现。(注意:无需对抽象类或抽象成员标注open注解,open注解用法将在下篇文章讲到)

嵌套类和内部类

我们可以把一个类嵌套在其他类中,这种类称作嵌套类。而内部类使用inner关键字来表示。内部类会带有一个对外部类的对象的引用,所以内部类可以访问外部类成员属性和成员函数。

有的时候,为了消除歧义更好理解代码,要访问来自外部作用域的 this,我们使用this@label,其中 @label 是一个 代指 this 来源的标签。

class Outer {                  // 外部类
    private val num: Int = 100
    var value = "成员变量"
    class Nest {             // 嵌套类
        fun foo() = 2
    }
    inner class Inner {       // 内部类
        fun foo() = num  // 访问外部类成员
        fun innerTest() {
            var o = this@Outer //获取外部类的成员变量
            println("内部类可以引用外部类成员,例如:" + o.value)
        }
    }
}

fun main(args: Array<String>) {
    val demo = Outer.Nest().foo() // 嵌套类调用格式:外部类.嵌套类.嵌套类方法/属性
    println(demo)

    val inner = Outer().Inner().foo()
    println(inner) //   1
    val inTest = Outer().Inner().innerTest()
    println(inTest)   // 内部类可以引用外部类的成员属性等
}

对应控制台输出为:

这里需要注意的是,嵌套类和内部类在调用时的重要区别:

var nestDemo = Outer.Nest()// 嵌套类,Outer后边没有括号
var innerDemo = Outer().Inner();// 内部类,Outer后边有括号

匿名内部类

kotlin使用对象表达式来创建匿名内部类,使用方式与Java类似,以下为调用接口示例(如果对接口使用有疑问,不要慌,下一篇会讲到)。这里,object 是 Kotlin 的关键字,要实现匿名内部类,就必须使用 object 关键字,不能随意替换其它单词。

class Outer {
    var value = "成员变量"
    fun setInterFace(test: TestInterFace) {
        test.test()
    }
}

interface TestInterFace {
    fun test()
}

fun main(args: Array<String>) {
    var test = Outer()  //声明类对象

    test.setInterFace(object : TestInterFace{
        override fun test() {
            println("创建匿名内部类的实例")
        }
    })
}

类的修饰符

与Java类似,类的修饰符包含类属性修饰符(classModifier)和访问权限修饰符(accessModifier)。

类属性修饰符,标示类本身特性:

abstract    // 抽象类  
final       // 类不可继承,默认属性
enum        // 枚举类
open        // 类可继承,类默认是final的
annotation  // 注解类

访问权限修饰符:

private    // 仅在同一个文件中可见
protected  // 同一个文件中或子类可见
public     // 所有调用的地方都可见
internal   // 同一个模块中可见

示例如下:

// 文件名:LearnKotlin.kt
package ktlearn

private fun foo() {} // 在 LearnKotlin.kt 内可见

public var num: Int = 5 // 该属性随处可见

internal val nit = 6    // 相同模块内可见

End,如有问题请留言。

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

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

相关文章

vue实现查询搜索框下拉字典

字典表 前端页面显示 依据这个字典表实现动态查询 初始化数组 首先先在全局变量里定义一个数据存放查询出来的数据 data() {return {dicts: []};},生命周期 查询的时候是声明周期开始的时候&#xff0c;原本增删改查页面在生命周期开始的时候就查询了页面的数据获得了列表值…

IEEE| IceNet《IceNet for Interactive Contrast Enhancement》论文超详细解读(翻译+精读)

学习资料&#xff1a; 论文题目&#xff1a;《IceNet for Interactive Contrast Enhancement》&#xff08;用于交互式对比度增强的IceNet&#xff09;原文地址&#xff1a;export.arxiv.org/pdf/2109.05838v2.pdf 目录 ABSTRACT—摘要 翻译 精读 I. INTRODUCTION—简介 翻…

Thinkphp5.0.23远程代码执行漏洞复现

★★免责声明★★ 文章中涉及的程序(方法)可能带有攻击性&#xff0c;仅供安全研究与学习之用&#xff0c;读者将信息做其他用途&#xff0c;由Ta承担全部法律及连带责任&#xff0c;文章作者不承担任何法律及连带责任。 1、漏洞介绍 使用Thinkphp5.x远程代码执行漏洞&#xf…

26元/月起!腾讯云自动搭建4核16G雾锁王国服务器

腾讯云无需任何配置自动搭建雾锁王国4-8人联机服务器&#xff0c;游戏24小时在线&#xff0c;4核16G服务器低至26元/月起&#xff0c;一键搭建自己的雾锁王国联机服务器&#xff01; 第一步&#xff1a;购买服务器 1、通过【腾讯云游戏服专属优惠】页面&#xff0c;选择“雾锁…

关于v8垃圾回收机制以及与其相关联的知识点--还没整理版本

对于值类型b来说&#xff0c;就直接释放了其占用的内存&#xff0c;对于引用类型obj来说&#xff0c;销毁的只是变量obj对堆内存地址 1001 的引用&#xff0c;obj的值 { c: 3 } 依然存在于堆内存中。那么堆内存中的变量如何进行回收呢&#xff1f; V8的垃圾回收策略主要是基于…

YOLOv5改进系列(29)——添加DilateFormer(MSDA)注意力机制(中科院一区顶刊|即插即用的多尺度全局注意力机制)

【YOLOv5改进系列】前期回顾&#xff1a; YOLOv5改进系列&#xff08;0&#xff09;——重要性能指标与训练结果评价及分析 YOLOv5改进系列&#xff08;1&#xff09;——添加SE注意力机制 YOLOv5改进系列&#xff08;2&#xff09;——添加CBAM注意力机制 YOLOv5改进系列&…

Duplicate entry ‘2020045-2-1‘ for key ‘index_uid‘ 解决方案

项目场景&#xff1a; 今天小编在工作中编写接口对数据库增加相同的非主键数据的时候&#xff0c;突然出现了这样的一个错误&#xff1a; 下面我来给大家解答这个错误的出现原因以及解决办法。 问题描述 Duplicate entry 2020045-2-1 for key index_uid 这个错误大概意思就是…

Vue3-Composition-API(二)

一、computed函数使用 1.computed 在前面我们讲解过计算属性computed&#xff1a;当我们的某些属性是依赖其他状态时&#xff0c;我们可以使用计算属性来处理 在前面的Options API中&#xff0c;我们是使用computed选项来完成的&#xff1b; 在Composition API中&#xff0c…

Spring实现事务(一)

Spring事务 .什么是事务事务的操作Spring中事务的实现准备工作创建表创建项目,引入Spring Web, Mybatis, mysql等依赖配置文件实体类 编程式事务(手动写代码操作事务)声明式事务(利用注解自动开启和提交事务) . 什么是事务 事务是⼀组操作的集合, 是⼀个不可分割的操作 在我们…

基于布谷鸟搜索的多目标优化matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 1. 布谷鸟搜索算法基础 2. 多目标优化问题 3. 基于布谷鸟搜索的多目标优化算法 4. 解的存储和选择策略 5.算法步骤 5.完整程序 1.程序功能描述 基于布谷鸟搜索的多目标优化&#xff0c;…

JavaScript基础(二)—— 运算符、表达式与语句(if、switch、循环)

学习目标&#xff1a; 掌握常见运算符&#xff0c;为程序“能思考”做准备 掌握分支语句&#xff0c;让程序具备判断能力 掌握循环语句&#xff0c;让程序具备重复执行能力 一、运算符 1. 赋值运算符 对变量进行赋值的运算符&#xff0c;能够使用赋值运算符简化代码。 …

【解决视网膜长尾数据】关系子集学习、射击法、加权知识蒸馏

长尾分布下的视网膜&#xff1a;关系子集学习、射击法、加权知识蒸馏 核心思想问题&#xff1a;类别分布的不平衡问题问题&#xff1a;共现标签问题&#xff1a;特定区域和特征的类别关联解法&#xff1a;划分子集解决样本不平衡问题解法&#xff1a;射击法解决共现标签问题解法…

【缓存周总结】Redis缓存的使用以及数据安全的处理

前言 Redis非关系型数据库已经是很常见的工具了&#xff0c;项目中用到的也很多&#xff0c;这篇文章系统的分析下使用过程中可能会遇到的问题 一、缓存 缓存是数据交换的缓冲区&#xff0c;是存贮数据的临时地方&#xff0c;一般读写性能较高。 我们项目中引用的Redis目的就是…

Unity - 调节camera物理相机参数(HDRP)

在 “Hierarchy” 右键 -> Volume -> Global Volume new 一个 profile, 设置Mode为Pysical Camera 再点击camera组件&#xff0c;这时候设置 ISO、Shutter Speed、Aperture等参数值还会有效。

深入了解如何对IPA包进行有效的混淆处理

1、安装混淆工具 首先电脑上要安装ipagurad工具&#xff0c;官网链接&#xff1a;IpaGuard官网--IOS 应用程序ipa文件混淆加密保护工具 2、生成混淆文件 由于混淆需要首先 打开要处理的IPA文件 第一项&#xff0c;填写我们需要重签名的 ipa 路径&#xff08;当前导入的路径跟导…

跟着pink老师前端入门教程-day16

二十七、CSS3进阶 1、CSS3 2D转换 转换&#xff08;transform&#xff09;是CSS3中具有颠覆性的特征之一&#xff0c;可以实现元素的位移、旋转、缩放等效果 转换&#xff08;transform&#xff09;可以简单理解为变形 移动&#xff1a;translate&#xff1b;旋转&#xff…

【LVGL源码移植】

LVGL源码移植 ■ LVGL源码移植一&#xff1a;下载LVGL源码二&#xff1a;修改LVGL文件夹1: 将这5个文件&#xff0c;复制到一个新的文件夹2: 简化文件&#xff0c;减少内存消耗&#xff08;去除不必要的文件&#xff09;3: 为了规范化&#xff0c;我们将下列文件进行重命名 三&…

nodejs+vue+ElementUi宠物领养救助网站0w6wc

宠物领养救助平台采用B/S架构&#xff0c;数据库是MySQL。网站的搭建与开发采用了先进的nodejs进行编写&#xff0c;使用了vue框架。该系统从两个对象&#xff1a;由管理员和用户来对系统进行设计构建。主要功能包括&#xff1a;个人信息修改&#xff0c;对用户、宠物类别、宠物…

七、并发工具(上)

一、自定义线程池 1&#xff09;背景&#xff1a; 在 QPS 量比较高的情况下&#xff0c;我们不可能说所有的访问都创建一个线程执行&#xff0c;这会导致内存占用过高&#xff0c;甚至有可能出现 out of memory另外也要考虑 cpu 核数&#xff0c;如果请求超过了cpu核数&#…

【多个SpringBoot模块项目如何变成聚合项目】

【前言】 项目虽然是Eureka、OpenFeign 进行服务注册和服务调用&#xff0c;但是每个模块都是一个单独的SpringBoot&#xff0c;启动每个模块都需要单独启动一个idea,觉得这个过于繁琐&#xff0c;现在想把项目变成一个聚合项目&#xff0c;只需要启动一个idea即可。 【过程】…