Android开发知识学习——Kotlin基础

函数声明

声明函数要用用 fun 关键字,就像声明类要用 class 关键字一样
「函数参数」的「参数类型」是在「参数名」的右边
函数的「返回值」在「函数参数」右边使用 : 分隔,没有返回值时可以省略

  • 声明没有返回值的函数:
 fun main(){println("123")}
  • 声明有返回值的参数:
 fun sum(x:Int,y:Int):Int{println("123")}

变量声明

  • 声明变量需要通过关键字, var 声明可读可写变量, val 声明只读变量

  • 「类型」在「变量量名」的右边,用 : 分割,同时如果满足「类型推断」,类型可以省略

  • 创建对象直接调用构造器,不需要 new 关键字

  • 声明可读可写变量:

var x: Int= 1
  • 声明只读变量:
val username:String = "username"
  • 声明对象
val user:User = User()

类型推断

在变量声明的基础上,如果表达式右边的类型是可以推断出来,那么类型可以省略:

var age = 18
val name = "Hello"
val user = User()

继承类/实现接口

继承类和实现接口都是用的 : ,如果类中没有构造器 ( constructor ),需要在父类类名后面加上 () :

class MainActivity : AppCompatActivity(),View.OnClickListener{}

Java中是这样的

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
}

空安全设计

Kotlin 中的类型分为「可空类型」和「不可空类型」:

  • 不可空类型
val username: EditText
  • 可空类型
val username: EditText?

调用符

  • !! 强行调用符
  • ?. 安全调用符

lateinit 关键字

lateinit 关键字表示变量可以在其初始化表达式被执行之后进行初始化

  • lateinit 只能修饰 var 可读可写变量,因为 val 定义了变量是不可变的,必须在声明时进行初始化
  • lateinit 关键字声明的变量的类型必须是「不可空类型」
  • lateinit 声明的变量不能有「初始值」
  • lateinit 声明的变量不能是「基本数据类型」
    在构造器中初始化的属性不需要 lateinit 关键字

平台类型

在类型后面面加上一个感叹号的类型是「平台类型」,Java 中可以通过注解减少这种平台类型的产生

  • @Nullable 表示可空类型
  • @NotNull @NonNul l 表示不可空类型

类型判断

  • is 判断属于某类型
    在这里插入图片描述

  • !is 判断不属于某类型
    在这里插入图片描述

  • as 类型强转,失败时抛出类型强转失败异常
    在这里插入图片描述

  • as? 类型强转,但失败时不会抛出异常而是返回 null

获取 Class 对象

  • 使用 类名::class 获取的是 Kotlin 的类型是 KClass
MainActivity::class
  • 使用 类名::class.java 获取的是 Java 的类型
startActivity(Intent(this,test::class.java))

setter/getter

在 Kotlin 声明属性的时候(没有使用 private 修饰),会自动生成一个私有属性和一对公开的 setter/getter 函数。
在写 setter/getter 的时候使用 field 来代替内部的私有属性(防止递归栈溢
出)

class User {
var username : String?= null
var password : String?= nullset(value) {field = value}get() {return field}//构造器constructor(){}constructor(username : String?,password : String?){this.username = usernamethis.password = password}
}

为什么 EditText.getText() 的时候可以简化,但是 EditText.setText() 的时候不能和
TextView.setText() 一样简化?
因为 EditText.getText() 获得的类型是 Editable ,对应的如果EditText.setText() 传入的参数也是 Editable 就可以简化了。

val newEditable= Editable.Factory.getInstance().newEditable("Kotlin") et_username.text = newEditable 

构造器

使用 constructor 关键字声明构造器

    //构造器constructor(){}constructor(username : String?,password : String?){this.username = usernamethis.password = password}

如果我们在构造器主动调用了了父类构造,那么在继承类的时候就不能在类的后面加上小括号

constructor(context: Context) : this(context, null)
// 主动调用用了父类的构造器
constructor(context: Context, attr: AttributeSet?) :
super(context, attr)

@JvmField 生成属性

通过 @JvmField 注解可以让编译器只生成一个 public 的成员属性,不生成对应的 setter/getter 函数

   @JvmField
var username : String?= null
 User user = new User();String username = user.username;

Any 和 Unit

  • Any
    Kotlin 的顶层父类是 Any ,对应 Java 当中的 Object ,但是比Object 少了 wait()/notify() 等函数
class User : Any {}
  • Unit
    Kotlin 中的 Unit 对应 Java 中的 void
 fun get():Unit{}

数组

使用 arrayof() 来创建数组,基本数据类型使用对应的 intArrayOf() 等

val list:Array<String> = arrayOf("1", "2", "3", "4")
val Intlist:IntArray = intArrayOf(1, 2, 3, 4)

静态函数和属性

  • 顶层函数
    顶层函数,它并不依赖于任何特定对象或类。顶层函数可以在任何地方直接使用,不需要创建类的实例

类名.调用方法

class MyClass {fun greet(name: String): String {return "Hello, $name"}
}

然后你可以这样创建一个类的实例并调用它的方法:

val myClass = MyClass()  // Create an instance of MyClass
val greeting = myClass.greet("John")  // Call the greet() method on the instance
println(greeting)  // Prints: Hello, John
  • object
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • companion object
    在这里插入图片描述
    在这里插入图片描述
    其中,「顶层函数」直接在文件中定义函数和属性,会直接生成静态的,在 Java 中通过「文件名Kt」来 访问,同时可以通过 @file:JvmName 注解来修改这个「类名」。需要注意,这种顶层函数不要声明在 module 内最顶层的包中,至少要在一个包中例如 com 。不然不能方便使用。objectcompanion object 都是生成单例例对象,然后通过单例对象访问函数和属性的。

@JvmStatic

通过这个注解将 objectcompanion object 的内部函数和属性,真正生成为静态的。
通常使用 @JvmStatic 注解来标记那些需要在 JVM 中直接访问的静态方法或变量。当 Kotlin 代码被编译为 JVM 字节码时,注解处理器会将这些静态方法和变量插入到生成的 Java 类中
在这里插入图片描述
使用 @JvmStatic 注解标记了 greet() 方法。当这个 Kotlin 类被编译为 Java 类时,greet() 方法会被插入到生成的 Java 类中,并且可以直接通过类名来访问,而不需要创建 Kotlin 类的实例。

在 Java 中,你可以像这样调用 currentApplication() 方法:
在这里插入图片描述

单例模式/匿名内部类

通过 object 关键字实现

// 单例
object Singleton {
}
// 匿名内部类
object : Callback {
}

字符串

字符串模版

通过 ${} 的形式来作为字符串模版

val number = 100000000
val text = "支付宝收款${number}元。"
// 如果只是单一的变量,可以省略掉 {}
val text2 = "支付宝收款$number元。

多行字符串

val s = """
我是第一行
我是第二行
我是第三行
""".trimIndent()

区间

200…299 表示 200 -> 299 的区间(包括 299 )

300…399 表示 300 -> 399 的区间(包括 399 )

when 关键字

Java 当中的 switch 的高级版,分支条件上可以支持表达式
在这里插入图片描述

受检异常

Kotlin 不需要使用 try-catch 强制捕获异常

声明接口/抽象类/枚举/注解

// 声明抽象类
abstract class// 声明接口
interface// 声明注解
annotation class// 声明枚举
enmu class

编译期常量

在静态变量上加上 const 关键字变成编译期常量
const 关键字可以用来声明一个编译期常量。这个常量必须在声明时就赋值,而且必须是字面值,不能是函数调用或者表达式。此外,const 常量必须是只读的,不能在运行时修改
在这里插入图片描述

标签

  • 在 Java 中通过 「 类名.this 例如 Outer.this 」 获取目标类引用
    在这里插入图片描述

  • 在 Kotlin 中通过「 this@类名 例如 this@Outer 」获取目标类引用
    在这里插入图片描述

遍历

记得让 IDE 来帮助生成 for 循环

for(item in items)

在这里插入图片描述

内部类

Kotlin 当中,内部类默认是静态内部类
通过 inner 关键字声明为嵌套内部类
在这里插入图片描述

可见性修饰符

默认的可⻅性修饰符是 public
新增的可⻅性修饰符 internal 表示当前模块可⻅

注释

注释中可以在任意地方使用 [] 来引用目标,代替 Java 中的 @param @link等。

非空断言

可空类型强制类型转换成不可空类型可以通过在变量后面加上 !! ,来达到类型转换。

open/final

Kotlin 中的类和函数,默认是被 final 修饰的 ( abstractoverride 例外)

课后题

  1. kotlin编译器会默认创建构造函数吗

在Kotlin中,构造函数与类的其他部分一样,需要进行显式声明。如果你没有声明构造函数,Kotlin编译器会为你生成一个默认的无参构造函数。这个默认构造函数不会调用任何代码,即它是一个空函数

  1. var username : String?= “123”

声明一个名为 username 的可变变量,它的类型是 String?(可空字符串),并初始化为 “123”。如果你需要改变
username 的值,你可以直接给它赋值一个新的字符串或者 null

  1. public var age : Int = 0

在 Kotlin 中,public var age : Int = 0@JvmField var age : Int = 0
都可以用来在 Kotlin 中声明一个公共的、可变的、初始化为 0 的整型变量。然而,这两者并不完全等价。 public var age : Int = 0 是直接在 Kotlin 中声明变量,其默认的可见性就是 public,也就是可以被任何其他代码访问。 而
@JvmField var age : Int = 0 是使用注解 @JvmField,这会生成一个在 Java
中可见的字段。@JvmField 的目的是让 Kotlin 中的变量在 Java 代码中以字段的形式表现出来,而不是通过
gettersetter 方法访问。 这两者的主要区别在于,如果你需要在 Java 中直接访问 Kotlin 变量(而不是通过
getter 和 setter),那么你需要使用 @JvmField。如果你只是在 Kotlin 内部或者在其他支持 Kotlin
的地方使用这个变量,那么你可以直接使用 public var age : Int = 0
总的来说,这两者并不是互为替代的关系,而是根据具体的使用场景来选择使用哪一种。

  • 举例:
    假设你有以下 Kotlin 类定义:
class Person {var name: String = "John"@JvmField var age: Int = 0
}

如果你使用 @JvmField,你可以在 Java 中直接访问和修改 age 变量,如下所示:

Person person = new Person();
person.age = 25; // 可以直接修改 age 变量
int age = person.age; // 通过字段获取 age 值

但是,如果你移除 @JvmField 并使用 public var age: Int = 0,你仍然可以在 Kotlin 中直接访问和修改 age 变量,但是在 Java 中需要通过 getter 和 setter 方法访问它:

Person person = new Person();
person.setAge(25); // 通过 setter 方法修改 age 值
int age = person.getAge(); // 通过 getter 方法获取 age 值

因此,使用 @JvmField 的主要目的是为了在 Java 中直接访问 Kotlin 属性,而无需使用 getter 和 setter 方法。如果你只在 Kotlin 中使用该属性,那么使用 public var age: Int = 0 就足够了。然而,如果你需要与 Java 代码进行互操作,并希望在 Java 中直接访问 Kotlin 属性,那么使用 @JvmField 是更合适的选择。

  1. Kotlin中的this.
    在Kotlin中,this关键字有特殊的意义。它被用来引用当前对象实例。
    在Kotlin中,this关键字有几种用法:
  • 直接引用当前对象的实例:在类的方法中,你可以使用this关键字来引用当前正在执行的对象实例。例如:
class MyClass {var name: String? = nullfun printName() {println(this.name)}
}

在这个例子中,this关键字引用的是正在执行的对象实例,该实例的name属性被打印出来。

  • 引用当前对象的属性或方法:当你需要通过对象来访问其属性或方法时,可以使用this关键字。例如:
class MyClass {var name: String? = nullfun printName() {println(this.name)}
}

在这个例子中,this关键字引用的是正在执行的对象实例,该实例的name属性被打印出来。

  • 在匿名函数或Lambda表达式中引用外部变量:在匿名函数或Lambda表达式中,你可以使用this关键字来引用外部的变量。例如:
fun outerFunction() {val x = 10val action = object : Action<Int> {override fun run(input: Int) {println("Value of x from outer function: $x") // Here, 'this' refers to the outer function's 'x' variable.}}action.run(5)
}

在这个例子中,this关键字引用的是外部函数的变量x。

  1. 【作文题】 使用 Kotlin 获得外部类引用的代码

val outer = /* 外部类引用 */

如果你想在 Kotlin 中获取对外部类的引用,你需要首先将该外部类定义为可访问的,然后你可以在内部类中直接引用它。
例如,假设你有一个名为 OuterClass 的外部类,并且你想在内部类 InnerClass 中获取该类的引用。你可以这样做:

class OuterClass {var name: String? = null
}class InnerClass {val outer: OuterClass? = nullfun printOuterName() {outer?.let {println("Name of the outer class: ${it.name}")}}
}

在这个例子中,OuterClass 是一个外部类,InnerClass 是一个内部类。在 InnerClass 中,我们声明了一个
outer 变量,它是 OuterClass 的一个引用。然后,在 printOuterName 方法中,我们通过 outer
变量访问了外部类的 name 属性。

  1. 【作文题】 下面的 Person 是不是 interface,为什么?

class User : Person()

在您提供的代码中,Person 并不是一个接口,而是一个类。您使用的是 Kotlin 语言,它支持通过冒号(:)来实现接口或类的继承。
在这段代码中,User 类通过使用 : 来继承 Person 类。这表示 User 是 Person 的子类,它继承了 Person 的属性和方法。
如果 Person 是一个接口,那么应该使用 interface Person 来声明。所以在这个代码片段中,Person 不是接口,它是一个类。

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

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

相关文章

怎么测量直线模组的精度?

直线模组是一款比较多变的一种产品&#xff0c;适合多种行业&#xff0c;同时它也适合比较多的环境&#xff0c;是一种比较全面的直线运动的装置。直线模组是非常精密的自动化机械设备&#xff0c;在实践中&#xff0c;应该要严格把握具体精度&#xff0c;并且在必要的时候&…

【嵌入式开发工具】STM32+Keil实现软件工程搭建与开发调试

本篇文章介绍了使用Keil来对STM32F103C8芯片进行初始工程搭建&#xff0c;以及开发与工程调试的完整过程&#xff0c;帮助读者能够在实战中体会到Keil这个开发环境的使用方法&#xff0c;了解一个嵌入式工程从无到有的过程&#xff0c;并且具备快速搭建一个全新芯片对应最小软件…

基于元学习神经网络的类人系统泛化

Nature 上介绍了一个关于AI在语言泛化方面的突破性研究。科学家们创建了一个具有人类般泛化能力的AI神经网络&#xff0c;它可以像人类一样将新学到的词汇融入现有词汇&#xff0c;并在新环境中使用它们。与ChatGPT 相比&#xff0c;该神经网络在系统性泛化测试中表现得更好。 …

17、Flink 之Table API: Table API 支持的操作(1)

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…

vite安装Tailwind CSS

安装 - Tailwind CSS 中文网 (nodejs.cn) 这是官网&#xff0c;平常我练习一般会用vite脚手架 我们选择这个vite模块 可选择React和Vue版本的&#xff0c;这里选择react的按照操作&#xff0c;没问题的话就要出问题了 1、在npm run dev的时候我是出现了这么个问题&#xff0c…

234. 回文链表、Leetcode的Python实现

博客主页&#xff1a;&#x1f3c6;看看是李XX还是李歘歘 &#x1f3c6; &#x1f33a;每天分享一些包括但不限于计算机基础、算法等相关的知识点&#x1f33a; &#x1f497;点关注不迷路&#xff0c;总有一些&#x1f4d6;知识点&#x1f4d6;是你想要的&#x1f497; ⛽️今…

竞赛 深度学习疫情社交安全距离检测算法 - python opencv cnn

文章目录 0 前言1 课题背景2 实现效果3 相关技术3.1 YOLOV43.2 基于 DeepSort 算法的行人跟踪 4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习疫情社交安全距离检测算法 ** 该项目较为新颖&#xff0c;适合作为竞赛…

【网络奇遇记】那年我与计算机网络的初相识

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;《网络奇遇记》 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. 信息时代的计算机网络二. 计算网络的定义和分类三. 计算机网络的特点四. 计算机网路在信息时代的应用五…

图解Linux进程优先级

目录 1.什么是进程优先级&#xff1f; 2.进程优先级原理 3.查看进程优先级 4.修改进程优先级 4.1 setpriority函数原型 4.2 getpriority函数原型 4.3 sched_setscheduler函数原型 4.4 sched_getscheduler函数原型 4.5 sched_setparam函数原型 4.6 sched_getparam函数…

Unity Perception合成数据生成、标注与ML模型训练

在线工具推荐&#xff1a; Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 3D场景编辑器 任何训练过机器学习模型的人都会告诉你&#xff0c;模型是从数据得到的&#xff0c;一般来说&#xff0c;更多的数据和标签会带来更好的性能。 …

限制LitstBox控件显示指定行数的最新数据(3/3)

实例需求&#xff1a;由于数据行数累加增加&#xff0c;控件加载的数据越来越多&#xff0c;每次用户都需要使用右侧滚动条拖动才能查看最新数据。 因此希望ListBox只加载最后10行数据&#xff08;不含标题行&#xff09;&#xff0c;这样用户可以非常方便地选择数据&#xff…

JMeter组件

1.JMeter常用组件 必须组件&#xff1a;测试计划&#xff0c;线程组&#xff08;包含多个线程&#xff09;&#xff0c;取样器 测试计划&#xff0c;JMeter默认创建且仅有一个 线程组&#xff1a; 添加步骤&#xff1a; 选择TestPlan并点击鼠标右键添加 分类以及使用&…

Spring Data Redis + RabbitMQ - 基于 string 实现缓存、计数功能(同步数据)

目录 一、Spring Data Redis 1.1、缓存功能 1.1.1、分析 1.1.2、案例实现 1.1.3、效果演示 1.2、计数功能&#xff08;Redis RabbitMQ&#xff09; 1.2.1、分析 1.2.2、案例实现 一、Spring Data Redis 1.1、缓存功能 1.1.1、分析 使用 redis 作为缓存&#xff0c; M…

curl(四)证书相关

一 证书相关 ① -k 1、客户端忽略服务端证书校验 -k | --insecure --> 单向[1]、这个选项显式地允许curl 执行不安全 的SSL连接和传输[2]、所有SSL连接都试图通过使用默认安装的CA证书捆绑包来确保安全[3]、这使得所有被认为是不安全的连接失败,除非使用-k --> 自签…

一座 “数智桥梁”,华为助力“天堑变通途”

《水调歌头游泳》中的一句话&#xff0c;“一桥飞架南北&#xff0c;天堑变通途”&#xff0c;广为人们所熟知&#xff0c;其中展现出的&#xff0c;是中国人对美好出行的无限向往。 天堑变通途从来不易。 中国是当今世界上交通运输最繁忙、最快捷的国家之一&#xff0c;交通行…

2023-在mac下安装Homebrew的国内镜像

mac安装Homebrew的国内镜像 尝试使用其他下载源&#xff1a;GitHub 可能会受到访问限制&#xff0c;尝试使用其他镜像或下载源。您可以使用清华大学、中科大或阿里云的 Homebrew 镜像&#xff0c;以提高下载速度和可靠性。例如&#xff0c;可以使用阿里云的镜像来安装 Homebre…

任务1 部署ChatGLM3-6B大模型并进行对话测试

部署ChatGLM3-6B大模型并进行对话测试 0 介绍&#xff1a;1 趋动云项目创建与环境配置1.1 创建项目&#xff1a;1.2 配置环境1.2.1 进入终端1.2.2 设置镜像源1.2.3 克隆项目,并安装依赖 2 修改代码&#xff0c;改路径以及启动代码3 运行代码3.1 运行gradio界面&#xff1a;3.2 …

雷池WAF社区版的使用教程

最近听说了一款免费又好用的WAF软件&#xff0c;雷池社区版&#xff0c;体验了一下虽然还有很多改进的空间 但是总体来说很适合小站长使用&#xff0c;和学习使用 也建议所有想学防火墙和红队&#xff08;攻击队&#xff09;练习使用&#xff0c;听说给官网提交绕过还有额外的…

ZKP Introduction of Nova (Yu Guo) 手写笔记

ZKP学习笔记 郭宇老师Nova课程手写笔记

你知道Python、Pycharm、Anaconda 三者之间的关系吗?

哈喽~大家好呀 Python作为深度学习和人工智能学习的热门语言&#xff0c;你知道Python、Pycharm、Anaconda 三者之间的关系吗&#xff1f;学习一门语言&#xff0c;除了学会其简单的语法之外还需要对其进行运行和实现&#xff0c;才能实现和发挥其功能和作用。下面来介绍运行P…