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

news2025/7/28 9:26:28

函数声明

声明函数要用用 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?= null
    
    set(value) {
        field = value
    }
    
    get() {
        return field
    }
    
    //构造器
    constructor(){
        
    }

    constructor(username : String?,password : String?){
        this.username = username
        this.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 = username
        this.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)

静态函数和属性

  • 顶层函数
    类名.调用方法
    在这里插入图片描述

  • object
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • companion object
    在这里插入图片描述
    在这里插入图片描述
    其中,「顶层函数」直接在文件中定义函数和属性,会直接生成静态的,在 Java 中
    通过「文件名Kt」来 访问,同时可以通过 @file:JvmName 注解来修改这个「类
    名」。
    需要注意,这种顶层函数不要声明在 module 内最顶层的包中,至少要在一个
    包中例如 com 。不然不能方便使用。
    objectcompanion object 都是生成单例例对象,然后通过单例对象访问
    函数和属性的。

@JvmStatic

通过这个注解将 objectcompanion object 的内部函数和属性,真正生成为静态的。
在这里插入图片描述

单例模式/匿名内部类

通过 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 关键字变成编译期常量
在这里插入图片描述

标签

  • 在 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编译器会为你生成一个默认的无参构造函数。这个默认构造函数不会调用任何代码,即它是一个空函数

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

  3. 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? = null

    fun printName() {
        println(this.name)
    }
}

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

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

    fun printName() {
        println(this.name)
    }
}

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

  • 在匿名函数或Lambda表达式中引用外部变量:在匿名函数或Lambda表达式中,你可以使用this关键字来引用外部的变量。例如:
fun outerFunction() {
    val x = 10
    val 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? = null

    fun 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.coloradmin.cn/o/1156496.html

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

相关文章

阿里云发布通义千问2.0,性能超GPT-3.5,加速追赶GPT-4

10月31日&#xff0c;阿里云正式发布千亿级参数大模型通义千问2.0。在10个权威测评中&#xff0c;通义千问2.0综合性能超过GPT-3.5&#xff0c;正在加速追赶GPT-4。当天&#xff0c;通义千问APP在各大手机应用市场正式上线&#xff0c;所有人都可通过APP直接体验最新模型能力。…

聊一聊B端产品和C端产品的区别

To C 和 To B 的产品究竟有什么区别&#xff1f;难道仅仅只是使用对象和买单者不一样嘛&#xff1f;刚入行的产品经理是不是傻傻分不清楚&#xff1f;做产品经理这么久的你是否思考过这个问题&#xff1f; 作为一名产品经理&#xff0c;也设计过To B 和 To C的产品&#xff0c…

13年测试老鸟,软件测试经验总结分享,这几年你走了多少坑...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、测试阶段划分 …

个性化医疗:数字孪生的未来之路

数字孪生技术已经成为医疗领域的一项重要创新&#xff0c;为医疗保障提供了全新的可能性。它基于数学、物理和计算机科学原理&#xff0c;通过创建数字化模型和仿真来模拟生物系统和医疗设备。 1. 个性化治疗 数字孪生技术可创建患者的个性化模型&#xff0c;以更好地了解疾病…

Python 自动化(十六)静态文件处理

准备工作 将不同day下的代码分目录管理&#xff0c;方便后续复习查阅 (testenv) [rootlocalhost projects]# ls day01 day02 (testenv) [rootlocalhost projects]# mkdir day03 (testenv) [rootlocalhost projects]# cd day03 (testenv) [rootlocalhost day03]# django-admi…

C语言 每日一题 day9

求最大值及其下标 本题要求编写程序&#xff0c;找出给定的n个数中的最大值及其对应的最小下标&#xff08;下标从0开始&#xff09;。 输入格式 : 输入在第一行中给出一个正整数n&#xff08;1 < n≤10&#xff09;。第二行输入n个整数&#xff0c;用空格分开。 输出格式 …

Nodejs和npm的使用方法和教程

Nodejs简介 Node.js 是一个开源和跨平台的 JavaScript 运行时环境。 它几乎是任何类型项目的流行工具&#xff01; &#xff08; 运行环境&#xff0c;是不是很熟悉&#xff0c;对。就是 java JRE&#xff0c;Java 运行时环境&#xff09; Node.js 在浏览器之外运行 V8 Java…

2023 CSP-J题解

T1 小苹果 题目描述 理论分析 对于第一问&#xff0c;我们按照题意模拟每天取走的是多少个苹果即可。由于每天可以取走原来的,数据范围没次会降低到&#xff0c;也就是说这样的过程的时间复杂度可以用下式表示&#xff1a; 对于本题的数据范围n<1e9&#xff0c;这个时间复杂…

PHP/MySQL开发本地服务器软件 MAMP Pro for Mac

MAMP Pro是一款专为Mac用户设计的全功能本地服务器软件&#xff0c;可以将电脑变成一个完整的Web开发环境。无论个人开发者、网站管理员还是团队协作&#xff0c;MAMP Pro都提供了强大的工具和便捷的管理方式&#xff0c;能够更加高效地构建和测试网站。 MAMP Pro的基本功能包括…

数字IC前端学习笔记:优化的基4布斯编码华莱士树乘法器

相关阅读 数字IC前端https://blog.csdn.net/weixin_45791458/category_12173698.html 本文是对前文设计的乘法器&#xff0c;即基4布斯编码华莱士树乘法器的补充和优化&#xff0c;具体关于基4布斯编码和华莱士树的内容可以从以往的文章中获得。 数字IC前端学习笔记&#xff…

信息系统项目管理师教程 第四版【第11章-项目成本管理-思维导图】

信息系统项目管理师教程 第四版【第11章-项目成本管理-思维导图】 课本里章节里所有蓝色字体的思维导图

【HarmonyOS】ArkTS学习之二级菜单的实现

【关键词】 Menu、bindMenu、ArkTS 【实现方案】 方案一&#xff1a; 1、实现代码&#xff1a; Entry Component struct MenuExample {BuildermyMenu(){Menu(){MenuItem({content: 编译 Hap(s)})MenuItem({content: 编译 APP(s)})}}BuildersubMenu(){Menu(){MenuItemGroup(…

一次cs上线服务器的练习

环境&#xff1a;利用vm搭建的环境 仅主机为65段 测试是否能与win10ping通 配置转发 配置好iis Kali访问测试 现在就用burp抓取winser的包 开启代理 使用默认的8080抓取成功 上线

【向生活低头】win7打印机共享给win11使用,win11无法连接问题的解决

打印机是跟win7的电脑连接的&#xff0c;然后试了很多方法&#xff0c;win11都没法添加该打印机去使用。 网上的方法乱七八糟啥都有&#xff0c;但试了以后&#xff0c;发现基本没什么用。 刚刚发现知乎上的一个回答是有用的&#xff0c;这里做记录以备后用。 1.打开控制面板的…

cocosCreator 调用wxAPI 及后台授权设置、获取用户昵称和头像

版本&#xff1a; 3.8.0 语言&#xff1a; TypeScript 环境&#xff1a; Mac 官方文档&#xff1a; 微信官方文档 - 开放能力 微信 API 小游戏环境 在cocosCreator的3.x版本项目开发中&#xff0c;TypeScript最终会被转换为JavaScript语言。 JavaScript的运行时调用的API…

图解系列--L2交换机

大端&#xff0c;小端 网络上传输时&#xff0c;采用网络字节序。网络字节序为大端序。举例来说&#xff0c;对0x1020这样一个数值&#xff0c;按大端传输时&#xff0c;先传输0x10&#xff0c;再传输0x20&#xff1b;按小端传输时&#xff0c;先传输0x20&#xff0c;再传输0x…

Qt 中model/View 架构 详解,以及案例实现相薄功能

model/View 架构 导读 ​ 我们的系统需要显示大量数据,比如从数据库中读取数据,以自己的方式显示在自己的应用程序的界面中。早期的 Qt 要实现这个功能,需要定义一个组件,在这个组件中保存一个数据对象,比如一个列表。我们对这个列表进行查找、插入等的操作,或者把修改…

k8s---pod进阶

//资源限制 当定义 Pod 时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是 CPU 和内存大小&#xff0c;以及其他类型的资源。 当为 Pod 中的容器指定了 request 资源时&#xff0c;调度器就使用该信息来决定将 Pod 调度到哪个节点上。当还为容器指定了 li…

super(props)与react类式组件

1 为什么super() super是对父类构造器的调用。使用了后会自动继承父类的属性。要把super&#xff08;&#xff09;放到第一行是因为了以防在super&#xff08;&#xff09;之前&#xff0c;也就是没实例化父类之前&#xff0c;访问父类的属性。所以js将此作为一个语法点&#x…

机器视觉能不能再火爆?大多数企业订单减少是现实,大多数企业维持现有的经营状态将会非常困难,就看人工智能和新兴产业能不能破门而入

每个人都讲机器视觉代替大量人工&#xff0c;可是真的吗&#xff1f;没有订单&#xff0c;人工的存在都没必要&#xff0c;需要什么机器视觉检测。 我们首先有一个问题&#xff0c;机器视觉行业之前有没有火爆过&#xff1f; 有&#xff0c;但是出现短暂之后是内卷。深度学习A…