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.rhkb.cn/news/179300.html

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

相关文章

微信小程序上传图片和上传视频的组件失效

微信小程序上传图片和上传视频的组件失效 今天公司的小程序展示图片和视频文字的页面上传图片组件突然失效&#xff0c;之前用的好好的&#xff0c;突然所有使用都都发现用不了&#xff0c;以为是代码出现问题&#xff0c;反复查了很久。换了一个openid居然就可以了&#xff0…

jeecg-uniapp 转成小程序的过程 以及报错 uniapp点击事件

uniapp 点击事件 tap: 单击事件 confirm: 回车事件 blur:失去焦点事件 touchstart: 触摸开始事件 touchmove: 触摸移动事件。 touchend: 触摸结束事件。 longpress: 长按事件。 input: 输入框内容变化事件。 change: 表单元素值变化事件。 submit: 表单提交事件。 scroll: 滚动…

Seata入门系列【19】分布式事务之CAP、BASE理论

1 CAP理论 CAP是以下三个词语的缩写&#xff1a; Consistency&#xff1a;一致性Availability&#xff1a;可用性Partition tolerance&#xff1a;分区容忍性 CAP理论的基础概念就是在分布式系统中&#xff0c;无法同时满足以上三点。 下面我们以一个简单的分布式系统&…

如何提高Python图像表格数据提取的准确率?

Python图像表格数据提取 1、数据来源2、目标图像3、图像文本提取4、图像灰度化与二值化可以提高识别准确率吗1、数据来源 国家统计局:http://www.stats.gov.cn/sj/ 数据来源:国家统计局中国统计年鉴2022年人口数及构成 2、目标图像 数据(部分)如下: 数据形式:http://www…

docker打包container成image,然后将image上传到docker hub

第一步&#xff1a;停止正在运行的容器 docker stop <container_name> eg: docker stop xuanjie_mlir 第二步&#xff1a;将对应的container打包成image docker commit <container_id> <镜像名&#xff1a;版本> eg&#xff1a;docker commit 005672e6d97a…

MPLAB X IDE 仿真打断点提示已中断的断点?

这种中间带裂缝的是无效断点。 原因可能与XC编译器的优化有关&#xff0c;最后生成的汇编与C语言并不是一一对应的(官方给的解释是效率高)。所以这一行C语言转换的汇编代码可能并不在这个位置&#xff0c;也可能与其它汇编合并后根本就没有 我的解决方法是把优化等级调到最低&a…

导轨电表适不适合家用?

导轨电表&#xff0c;作为一种新型的电能计量设备&#xff0c;近年来在我国得到了广泛的应用。然而&#xff0c;对于家用市场来说&#xff0c;导轨电表是否适用仍然存在争议。那么&#xff0c;导轨电表适不适合家用呢&#xff1f;接下来&#xff0c;小编来为大家讲解下&#xf…

计算机网络第4章-网络层(1)

引子 网络层能够被分解为两个相互作用的部分&#xff1a; 数据平面和控制平面。 网络层概述 路由器具有截断的协议栈&#xff0c;即没有网络层以上的部分。 如下图所示&#xff0c;是一个简单网络&#xff1a; 转发和路由选择&#xff1a;数据平面和控制平面 网络层的作用…

精选8款UML图工具,闭眼入!

在现代软件开发领域&#xff0c;UML&#xff08;统一建模语言&#xff09;图是不可或缺的工具之一&#xff0c;用于可视化和通信复杂系统的结构和设计。然而&#xff0c;在选择合适的UML图工具时&#xff0c;你需要考虑多个因素&#xff0c;如项目规模、团队协作需求、功能复杂…

Docker dnmp 多版本php安装 php8.2

Laravel9 开发需要用到php8.1以上的版本&#xff0c;而dnmp只支持到php8.0。安装php8.2的步骤如下&#xff1a; 1. 从/services/php80目录复制一份出来&#xff0c;重命名为php82&#xff0c;extensions目录只保留 install.sh 和 install-php-extensions 这两个文件 2. 修改.en…

苹果IOS系统webglcontextlost问题-解决方案

问题描述 在IOS手机 解码视频流的时候&#xff0c;第一次可以正常播放&#xff0c;但只要IOS手机熄屏&#xff0c;再重新唤醒&#xff0c;就会一直播放失败&#xff0c;无论换哪个浏览器都不行。安卓手机则一切正常。 经过排查&#xff0c;发现 IOS手机 的浏览器会无故 webGL…

突破性技术!开源多模态模型—MiniGPT-5

多模态生成一直是OpenAI、微软、百度等科技巨头的重要研究领域&#xff0c;但如何实现连贯的文本和相关图像是一个棘手的难题。 为了突破技术瓶颈&#xff0c;加州大学圣克鲁斯分校研发了MiniGPT-5模型&#xff0c;并提出了全新技术概念“Generative Vokens "&#xff0c…

新工业革命?基于机器视觉技术分拣机器人的未来与发展

原创 | 文 BFT机器人 01 分拣机器人的应用 基于机器视觉技术的分拣机器人可以将工人从繁重的劳动中解放出来&#xff0c;大大提高了分拣的效率&#xff0c;因此被广泛地应用于食品、物流以及煤矿等多个行业。 1.1 分拣机器人在水果分拣中的应用 随着农业科技的发展和人民生活…

SOLIDWORKS参数化设计之部分打包 慧德敏学

参数化设计就是通过主参数来驱动整个模型的变化&#xff0c;类似于SOLIDWORKS的方程式中&#xff0c;使用全局变量来控制模型其它参数的变化&#xff0c;因此要做参数化就必须要确定好主参数以及变化逻辑。 我们之前介绍过SOLIDWORKS参数化设计软件-SolidKits.AutoWorks&#…

软件设计模式原则(二)开闭原则

继续讲解第二个重要的设计模式原则——开闭原则~ 一.定义 开闭原则(Open Closed Principle&#xff09;是编程中最基础、最重要的设计原则。一个软件实体如类&#xff0c;模块和函数应该对扩展开放(对提供方)&#xff0c;对修改关闭(对使用方)。用抽象构建框架&#xff0c;用实…

关于FastJSON序列化Bean时对get方法调用的细节

结论 使用JSON.toJSONString去序列化Bean的时候 FastJSON会把Bean里面的get开头&#xff0c;有返回值且没有参数的方法都调用一遍。 看代码 package org.example.domain;import lombok.Getter; import lombok.Setter;/*** program: parent_pro* description:* author: 渭水* c…

presto插件机制揭秘:探索无限可能的数据处理舞台

文章目录 1. 前言2. Presto插件架构3. Plugin接口3.1 插件协议3.2 插件实现类 4. 插件加载过程4.1 PluginManager 5. 插件应用6. 总结 关键词&#xff1a;Presto Plugin 1. 前言 本文源码环境&#xff1a; presto: prestoDb 0.275版本 在Presto框架中插件机制设计是一种非常常见…

备忘录在电脑里叫什么?Win10系统自带的备忘录在哪打开?

对于每天都需要使用电脑来办公的职场人士来说&#xff0c;能够随手在电脑桌面上记录工作笔记、常用工作资料、工作注意事项等内容是非常有必要的。但是如果想要实现在电脑上随手记录事情&#xff0c;就需要先找到一款类似于备忘录或便签软件那样的记事软件。 那么备忘录在电脑…

java实现pdf文件添加水印,下载到浏览器

java实现pdf文件添加水印&#xff0c;下载到浏览器 添加itextpdf依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.8</version> </dependency>文件下载到浏览器和指定路径 …

unity 使用TriLib插件动态读取外部模型

最近在做动态加载读取外部模型的功能使用了triLib插件&#xff0c;废话不多说直接干货。 第一步下载导入插件&#xff0c;直接分享主打白嫖共享&#xff0c;不搞花里胡哨的。 链接&#xff1a;https://pan.baidu.com/s/1DK474wSrIZ0R6i0EBh5V8A 提取码&#xff1a;tado 导入后第…