【Android】Kotlin教程(4)

news2024/11/8 21:03:54

文章目录

      • 1.field
      • 2.计算属性
      • 3.主构造函数
      • 4.次构造函数
      • 5.默认参数
      • 6.初始化块
      • 7.初始化顺序
      • 7.延迟初始化lateinit
      • 8.惰性初始化

1.field

field 关键字通常与属性的自定义 getter 和 setter 一起使用。当你需要为一个属性提供自定义的行为时,可以使用 field 来访问或设置该属性的实际存储值。

class Player {
    var age: Int = 0
        get() = field  // 自定义 getter
        set(value) {  // 自定义 setter
            if (value >= 0) {
                field = value
            } else {
                println("年龄不能为负数")
            }
        }
}

fun main() {
    val player = Player()

    player.age = 30  // 正常设置
    println(player.age)  // 输出 30

    player.age = -5  // 尝试设置无效的年龄
    println(player.age)  // 输出 30(因为设置失败,所以仍然是 30)
}

更复杂的自定义行为

class Person {
    private var _age: Int = 0  // 私有字段

    var age: Int
        get() {
            println("获取年龄: $_age")
            return _age
        }
        set(value) {
            if (value >= 0) {
                println("设置年龄: $value")
                _age = value
            } else {
                println("年龄不能为负数: $value")
            }
        }
}

fun main() {
    val person = Person()

    person.age = 30  // 输出: 设置年龄: 30
    println(person.age)  // 输出: 获取年龄: 30
                         //        30

    person.age = -5  // 输出: 年龄不能为负数: -5
    println(person.age)  // 输出: 获取年龄: 30
                         //        30
}
  • field 关键字:在自定义的 getter 和 setter 中,field 代表属性背后的实际存储字段。
  • 自定义 getter 和 setter:允许你在读取和写入属性时执行额外的逻辑,如数据验证、日志记录等。
  • 私有字段:为了更好地控制属性的访问,可以使用私有字段来存储实际值,并通过公开的属性提供访问接口。

2.计算属性

  • 计算属性:这些属性没有后台字段来存储值,而是通过 getter 方法在每次访问时计算并返回值。
  • 自定义 getter:你可以在类中定义一个没有显式初始化值的 val 属性,并为其提供一个自定义的 getter 方法。
class Rectangle(val width: Int, val height: Int) {
    // 计算属性
    val area: Int
        get() = width * height  // 自定义 getter
}

fun main() {
    val rectangle = Rectangle(10, 5)
    
    println("宽度: ${rectangle.width}")  // 输出 宽度: 10
    println("高度: ${rectangle.height}")  // 输出 高度: 5
    println("面积: ${rectangle.area}")  // 输出 面积: 50
}

3.主构造函数

在People类的定义头中定义一个主构造函数,使用临时变量为Player的各个属性提供初始值,在Kotlin中,为了便于识别临时变量通常都会以下划线开头的名字命名

class People(
    _name:String,
    _age:Int,
    _isNormal:Boolean
) {
    var name = _name
        get() = field.capitalize()
        set(value){
            field = value.trim()
        }
    var age = _age
        get() = field
        set(value){
            field = value.absoluteValue
        }
    var isNormal = _isNormal
}


fun main(){
    val people = People("Jack", 20, true)
    println(people.name)
    println(people.age)
    println(people.isNormal)
}

4.次构造函数

除了主构造函数还有次构造函数,我们可以定义多个次构造函数来配置不同的参数组合。

class People0(
    _name:String,
    var age:Int,
    var isNormal:Boolean
) {
    var name = _name
        get() = field.capitalize()
        set(value){
            field = value.trim()
        }

    constructor(name : String) : this(name , age = 10, isNormal = false) {
        this.name = name.capitalize()
    }

}


fun main(){


    val people0 = People0("rose")
    println(people0.name)  // Rose
    println(people0.age) // 0
    println(people0.isNormal) // false

}

5.默认参数

定义构造函数时,可以给构造函数指定默认值,如果用户调用时不提供值参,就是用这个默认值。

class People1(
    _name:String,
    var age:Int = 99,
    var isNormal:Boolean = false
) {
    var name = _name
        get() = field.capitalize()
        set(value){
            field = value.trim()
        }



    constructor(name : String) : this(name , age = 10, isNormal = false) {
        this.name = name.capitalize()
    }

}


fun main(){
    val people1 = People1(_name = "jim")
    println(people1.name) // Jim
    println(people1.age) // 99
    println(people1.isNormal) // false
}

6.初始化块

初始化块可以设置变量或值,以及执行有效性检查,如检查传给某构造函数的值是否有效,初始化块代码会在构造类实例时执行

class People1(
    _name:String,
    var age:Int = 99,
    var isNormal:Boolean = false
) {
    var name = _name
        get() = field.capitalize()
        set(value){
            field = value.trim()
        }



    constructor(name : String) : this(name , age = 10, isNormal = false) {
        this.name = name.capitalize()
    }


    init {
        require(age > 0){"年龄设置不能小于0"}
    }
}


fun main(){
    val people1 = People1(_name = "jim",-1, false)
    println(people1.name) // Jim
    println(people1.age) // 198
    println(people1.isNormal) // false
}

在这里插入图片描述

7.初始化顺序

  • 主构造函数里声明的属性
  • 类级别的属性赋值
  • init初始化块里的属性赋值和函数调用
  • 次构造函数里的属性赋值和函数调用
class Student(
    _name : String,
    val age : Int
){
    var name = _name

    var score = 10

    var hobby = "music"

    val subject : String


    init {
        println("initializing student...")
        subject = "Chinese"
    }

    constructor(_name:String) : this(_name,10){
        score = 100
    }
}

fun main(){
    val student = Student("Jack")

}
   public Student(@NotNull String _name) {
      Intrinsics.checkNotNullParameter(_name, "_name");
      this(_name, 10);
      this.score = 100;
   }
   public Student(@NotNull String _name, int age) {
      Intrinsics.checkNotNullParameter(_name, "_name");
      super();
      this.age = age;
      this.name = _name;
      this.score = 10;
      this.hobby = "music";
      String var3 = "initializing student...";
      System.out.println(var3);
      this.subject = "Chinese";
   }

在这里插入图片描述

7.延迟初始化lateinit

  • 使用lateinit关键字相当于做了一个约定:在用它之前负责初始化
  • 只要无法确认lateinit变量是否完成初始化,可以执行isInitialized检查
class Player4 {
    lateinit var equipment : String

    fun ready(){
        equipment = "AK-47"
    }

    fun battle(){
        if (::equipment.isInitialized){
            println(equipment)
        }else{
            println("没有武器")
        }

    }
}

fun main(){
    val player4 = Player4()
    // player4.ready()
    player4.battle()
}

8.惰性初始化

延迟初始化并不是初始化的唯一方式,你也可以暂时不初始化某个变量,知道首次使用它,叫做惰性初始化。

class Player5(_name :String) {
    var name = _name

    val config by lazy {
        loadConfig()
    }

    private fun loadConfig():String{
        println("loading...")
        return "xxx"
    }
}


fun main() {
    val p = Player5("kim")
    Thread.sleep(4000)
    // 4s后才会打印
    println(p.config)
}

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

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

相关文章

可以在线制作的PS网页版来了!

在当今数字化的创意时代,设计领域不断发展与变革,设计师们对于工具的需求也日益多样化和高效化。随着互联网技术的飞速进步,一种全新的设计工具模式应运而生——在线制作的 PS 网页版。它以其独特的优势和便捷性,逐渐成为众多设计…

高德地图如何添加自己店铺的位置信息?

众所周知,创业开店时,地理位置的选择至关重要。一个优越的地理位置不仅能显著提升店铺的可见度,还能有效吸引更多潜在顾客的光顾。而且,为了将店铺的客流量最大化,商家还需在地图平台上准确标注自己的位置信息&#xf…

【黄豆颗粒数据集】黄豆识别 机器视觉 深度学习(含数据集)

一、背景意义 随着全球农业生产的现代化,黄豆(大豆)作为一种重要的经济作物,广泛用于食品、饲料和工业原料的生产。准确识别和分类黄豆颗粒对于农业生产的管理、质量控制和市场分析具有重要意义。然而,传统的人工分类方…

JavaEE-多线程上

文章目录 线程概述进程/线程多线程的作用JVM关于线程资源的规范关于Java程序的运行原理 并发与并行并发(concurrency)并行(parallellism)并发编程与并行编程 线程的调度策略分时调度模型抢占式调度模型 创建线程线程类分析入门实现线程的第一种方式实现线程的第二种方式 线程的…

论文阅读:三星-TinyClick

《Single-Turn Agent for Empowering GUI Automation》 赋能GUI自动化的单轮代理 摘要 我们介绍了一个用于图形用户界面(GUI)交互任务的单轮代理,使用了视觉语言模型Florence-2-Base。该代理的主要任务是识别与用户指令相对应的UI元素的屏幕…

Tomcat servlet response关于中文乱码的经验

前言 最近修改老项目项目,使用zuul网关返回的中文内容乱码了,如果使用GBK或者GB2312编码确正常显示,稍微实验了一下,发现里面很多细节,毕竟Springboot对我们做了很多事情,而且当我们使用不同的模式会出现很…

服务器的免密登录和文件传输

在天文学研究中,通常会采用ssh登录服务器,把复杂的计算交给服务器,但是如果你没有进行额外的配置,那么登录服务器,以及和服务器进行文件传输,每次都要输入账号和密码,比较不方便,Win…

Windows Server NTFS磁盘变RAM的处理过程

问题描述 客户服务器的磁盘数据爆满,需要将磁盘进行扩容,因为是虚拟机所以先在虚拟化平台上将原来的磁盘空间改大,再进入系统,在磁盘管理器上将需要扩容的磁盘进行扩展。扩展完后系统报文件系统有问题,扩容的磁盘容量…

No.23 笔记 | WEB安全 - 任意文件漏洞 part 5

本文全面且深入地探讨了文件上传漏洞相关知识。从基础概念出发,清晰地阐述了文件上传漏洞的定义及其产生的本质原因,同时列出了该漏洞成立的必要条件。详细说明了文件上传漏洞可能对服务器控制权、网站安全以及业务运营带来的严重危害。 文中还深入解析了…

[mysql]子查询的概述和分类及单行子查询

子查询引入 查询的基本结构已经给大家了,子查询里面也是有一些新的内容,子查询其实就是在查询中嵌套另一个查询,叫嵌套查询可能大家更容易理解一点..,类似与FOR循环和FOR循环的嵌套,这一章是我们查询的最难的部分,大家 难度是查询的顶峰,多表查询和子查询是非常重要,SQL优化里…

EDA --软件开发之路

之前一直在一家做数据处理的公司,从事c开发,公司业务稳定,项目有忙有闲,时而看下c,数据库,linux相关书籍,后面跳槽到了家eda公司,开始了一段eda开发之路。 eda 是 electric design …

【移动应用开发】使用多媒体--通知/播放音频/视频

目录 一、具体步骤 二、运行截图 1. 开启通知权限 2. 播放音乐 3. 播放视频 三、源代码 1. activity_main.xml 2. activity_video_player.xml 3. activity_notification.xml 4. 一些配置 5. MainActivity 6. VideoPlayerActivity 7. NotificationActivity 8. And…

代码备份管理 —— Git实用操作

目 录 Git那些事版本控制系统git环境搭建运行bashbash命令行git账号全局设置本地仓库的存在远程仓库的存在git管理基本流程git仓库的文件夹常用git命令工作区变为git仓库add命令使用branch命令使用checkout命令使用commit命令使用仓库状态查询代码变更后提交删除或恢复文件管理…

windows下安装及使用labelme

1.进入Anaconda Prompt对话窗口 输入:conda create --namelabelme python3.6 # 创建一个叫labelme的环境 conda create --namelabelme python3.6 2.激活新建的环境,进入 输入:activate labelme #激活环境 activate labelme 3.安装pyqt5 …

集群渲染是一台节点输出吗?它是云渲染农场吗

集群渲染并非单一节点的输出,而是一种分布式计算技术,它通过多台计算机协同工作来加速3D渲染过程。这种技术常被视作云渲染农场的前身,两者在提高渲染效率方面有着相似之处。接下来,让我们深入了解集群渲染与云渲染农场之间的联系…

建筑行业内部知识库的重要性与实施策略

在当今瞬息万变的建筑行业中,企业面临着前所未有的竞争挑战。为了在市场中保持竞争力,建筑企业不仅需要拥有先进的技术和设备,还必须具备高效的知识管理能力。内部知识库,作为知识管理的核心工具,正逐渐成为建筑企业提…

【Fastjson反序列化漏洞:深入了解与防范】

一、Fastjson反序列化漏洞概述 Fastjson是一款高性能的Java语言JSON处理库,广泛应用于Web开发、数据交换等领域。然而,由于fastjson在解析JSON数据时存在安全漏洞,攻击者可以利用该漏洞执行任意代码,导致严重的安全威胁。 二、F…

数据结构 —— AVL树

目录 1. AVL的概念 2.AVL树的结构 3.AVL树的插入 3.1 平衡因子更新 4. 旋转 4.1 旋转的原则 4.2 右单旋 4.2.1 右单旋代码实现 4.3 左单旋 4.3.1 左单旋代码实现 4.4 左右双旋 4.4.1 左右双旋代码实现 4.5 右左双旋 ​编辑 4.5.1 右左双旋代码实现 5. AVL树的判断…

[GXYCTF 2019]Ping Ping Ping 题解(多种解题方式)

知识点: 命令执行 linux空格绕过 反引号绕过 变量绕过 base64编码绕过 打开页面提示 "听说php可以执行系统函数?我来康康" 然后输入框内提示输入 bjut.edu.cn 输入之后回显信息,是ping 这个网址的信息 输入127.0.0.1 因为提示是命令…

Python小游戏16——开心消消乐

运行结果显示 代码如下 import pygame import random # 初始化pygame pygame. init() # 定义一些常量 WIDTH 600 HEIGHT 600 NUM_GRID8 GRID_SIZE WIDTH // NUM_GRID FPS 30 # 定义颜色 WHITE (255, 255,255) BLACK(0,0,0) COL…