Android Kotlin 基础详解

news/2024/7/24 10:08:13 标签: kotlin, 开发语言, android

1,基础语法

1.1 可变变量与不可变变量

可以多次赋值的变量是可变变量,用关键字var表示:

var <标识符> : <类型> = <初始化值>  注意,在kotlin中成员变量不会赋默认值,不像java一样,必须手动添加默认值。
var name : String ="yuanzhen"
name ="yuanzhen1"
var age : Int =20
age =30
println("name:$name,age:$age")
输出:
name:yuanzhen1,age:30

只能赋值一次的变量,是不可变变量,用关键字val表示,类似于java里面的final:

val <标识符> : <类型> = <初始化值> 注意,在kotlin中成员变量不会赋默认值,不像java一样,必须手动添加默认值。

1.2类型推导

kotlin可以根据传入的值,自动推导出变量类型:

var name ="yuanzhen"  //类型推导
name ="yuanzhen1"
var age =20  //类型推导
age =30

1.3函数 方法

kotlin中的Unit相当于java中的void ,如果函数的返回值为Unit,可以不用写返回值

kotlin中使用fun关键字定义函数

定义一个有参数和返回值的函数:

fun test(name1:String ,name2:String):String{
    return name1+name2
}

   调用:

println(test("yuan","zhen"))
//输出 yuanzhen

   也可以根据类型推导,直接写成:

fun test(name1:String ,name2:String) =name1+name2

  可变参数用关键字vararg表示:

fun lenMethod(vararg value: Int) {
    for (i in value) {
        println(i)
    }
}

调用:

lenMethod(1, 2, 3, 4, 5, 6, 7)

1.4字符串

kotlin中,$表示一个变量名或者变量值,$name 表示变量值,如果变量值有多个,可以写为:${name1+name2}

var name ="yuanzhen1"  //类型推导
var name1 ="yuanzhen"
println("${name+name1}")

输出:yuanzhen1yuanzhen

换行:""" """  自己不用关心换行:

val infoMesage = """
    AAAAAAAAAAA
    BBBBBBBBBBB
    CCCCCCCCCCC
    DDDDDDDDDDD
    EEEEEEEEEEE
"""  // 前置空格
println(infoMesage)
val infoMesage2 = """
    AAAAAAAAAAA
    BBBBBBBBBBB
    CCCCCCCCCCC
    DDDDDDDDDDD
    EEEEEEEEEEE
""".trimIndent()  // 没空格
println(infoMesage2)
val infoMesage3 = """
    ?AAAAAAAAAAA
    ?BBBBBBBBBBB
    ?CCCCCCCCCCC
    ?DDDDDDDDDDD
    ?EEEEEEEEEEE
""".trimMargin("?")  // 没空格 控制?
println(infoMesage3)

输出:


    AAAAAAAAAAA
    BBBBBBBBBBB
    CCCCCCCCCCC
    DDDDDDDDDDD
    EEEEEEEEEEE

AAAAAAAAAAA
BBBBBBBBBBB
CCCCCCCCCCC
DDDDDDDDDDD
EEEEEEEEEEE
AAAAAAAAAAA
BBBBBBBBBBB
CCCCCCCCCCC
DDDDDDDDDDD
EEEEEEEEEEE

1.5 null检查机制

kotlin中,如果你这么定义一个变量,一定会报错的

因为这是kotlin特有的机制,不允许直接赋空值。那么要怎么做呢?

var age:Int?=null

加个?的意思就相当于 我发出了一个广播,告诉所有人这个值可能是空的,必须要有处理措施。

第一种处理措施:

var age:Int?=null
val i = age?.and(2)
println("$i")

输出:null

age?.and(2)的意思就是如果age是null,那就不执行?后面的内容了

第二种处理措施:

var age:Int?=null
age!!.and(2)

!!的意思就是我不管,我就强行执行and方法,出了事我负责。

第三种处理措施:

就跟java一样,自己判断处理

var age:Int?=null
if(age !=null){
    age.and(2)
}

1.6 区间

区间用..来表示

// 1 到 9
for (i in 1..9) {
    println(i)
}

输出 1 2 3 4 5 6 7 8 9

那如果这样写呢?

for (i in 9..1) {
    println(i)
}

注意:这样是不会输出的,因为没有9到1这种写法,那如果非要输出9到1呢?

for (i in 9 downTo 1) {
    println(i)
}

要用downTo

还可以指定步长:

for (i in 1..20 step 2) {
   println(i)
}

输出:1 3 5 7 9 11 13 15 17 19    每隔2输出一个值

排除最后一个元素:

for (i in 1 until 10) {
    println(i)
}

输出:1 2 3 4 5 6 7 8 9 

2, 比较与数组

2.1比较

在java中比较两个字符串,用equls来比较,但是在kotlin中,用==来比较字符串的值

val name1: String = "张三"
val name2: String = "张三"

println(name1 == name2)

比较对象地址用===表示

// ---  比较对象地址
val test1:Int? =  10000
val test2:Int? =  10000
println(test1 === test2)

输出false

2.2 数组

在java中数组有三种创建方式:

int[] array  = {1,2,3};
int[] array1 = new int[3];
int[] array2 = new int[]{7,8,9};

kotlin中 数组有两种方式:

第一种:

val numbers = arrayOf(1, 2, 3, 4, 5, 6, 7, 8)

第二种:

val numbers2 = Array(10,  {value: Int -> (value + 200) })
for (value in numbers2) {
    println(value)
}

输出:

200
201
202
203
204
205
206
207
208
209

为什么会这样呢? 因为value的默认值是0,之后会依次加一。

3,条件控制

比较大小值,可以这样写:

val number1: Int = 99
val number2: Int = 88
// 表达式 比 大小 最大值
val maxValue = if (number1 > number2) number1 else number2
println(maxValue)

输出99 

如果要执行多行代码,还可以这样写:

val max: Int = if (number1 > number2) {
    println("number1是最大的")
    number1
} else {
    println("number2是最大的")
    number2
}

注意:返回值不需要加return关键字

when相当于java中的switch case,只不过用法更加灵活

用于某个值:

val number5 = 5
when(number5) {
    1 -> println("一")
    2 -> println("二")
    3 -> println("三")
    4 -> println("四")
    5 -> println("五")
    else -> println("其他")
}

用于区间:

val number = 700
when(number) {
    in 1..100 -> println("1..100")
    in 200..500 -> println("200..500")
    else -> println("其他")
}

用于执行多行代码 并且有返回值:

val number = 3
val result = when (number) {
    1 -> {
        println("很开心")
        "今天是星期一"
        99
    }
    2 -> {
        println("很开心")
        "今天是星期二"
        88
    }
    3 -> {
        println("很开心")
        "今天是星期三"
        true
        100
    }
    else -> 99
}

4,循环与标签

4.1标签

自定义标签:在kotlin中,我们可以自定义一个标签,用来控制程序的执行流程等

yuanzhen@ for (i in 1..20) {
    for (j in 1..20) {
        println("i:$i, j:$j")
        if (i == 5) {
            // break // j循环 给break
            break@yuanzhen // i循环 给break
        }
    }
}

一个类中自带的标签:

class Yuan {

    val I = "aa"

    fun show() {
        println(I)
        println(this.I)
        println(this@Yuan.I)
    }

}

4.2循环

kotlin中,要遍历一个list,通常有三种方式:

var items  = listOf<String>("aaa", "bbb", "ccc")

方式一:

for (item in items) {
    println(item)
}

方式二:

items.forEach {
    println(it)
}

方式三:

for (index in items.indices) {
    println("下标:$index,  对应的值:${items[index]}")
}

5,类与对象

5.1类的创建

kotlin中,创建一个类,如果前面不写修饰符,默认就是public final 

// 默认就是public final
class Empty

这样是不能被继承的,要想被继承,就必须加上open

open class Person{}

5.2构造函数

在java中,会有一个默认的构造函数,并且可以重载无数个构造函数。

但是在kotlin中,它会有一个默认的主构造函数,其余的都是次构造。

上面的Person类,相当于有一个默认的主构造:

open class Person() // 主构造
{

}

那如果我们要给主构造增加一个参数呢?

open class Person(id: Int) // 主构造
{
}

那如果还要增加好几个次构造呢?

open class Person(id: Int) // 主构造
{

    // 次构造
    constructor(id: Int, name: String) : this(id) {

    }

    // 次构造
    constructor(id: Int, sex: Char) : this(id) {

    }

    // 次构造
    constructor() : this(222) {

    }

}

次构造必须继承主构造,同时把参数传给主构造

在使用时,可以这么用:

val person = Person() // 次构造
val person2 = Person(23456) // 主构造
Person(234, "yy") // 次构造
Person(234, 'M') // 次构造

5.3类的继承

继承父类用:表示

class Student(id: Int) : Person(id) // 主构造
{
    // 再Kotlin 全部都是没有默认值的

    // 再Java 成员有默认值,但是方法内部没有默认值

    // lateinit 懒加载  没有赋值 就不能使用,否则报错
    lateinit var name : String
    var age: Int = 0
}

5.4接口

kotlin中,接口和抽象类默认都是open的

interface Callback {

    fun callbackMethod() : Boolean

}
interface Callback2 {

    fun callbackMethod() : Boolean

}
abstract class Person : Callback , Callback2 {

    abstract fun getLayoutID() : Int

    abstract fun initView()

}
class Student : Person() {

    override fun getLayoutID(): Int = 888

    override fun initView() { }

    override fun callbackMethod(): Boolean  = false
}

与java差别不大

5.5data数据类

数据类是kotlin中独有的,在java中,我们要写数据类,通常会手写很多属性和方法等。

kotlin中,我们只需要用数据类定义属性就可以,不用关心get,set等方法,内部会自动帮我们生成。

// 会自动生成get set 构造 equals hashCode toString copy
data class User(val id: Int, val name: String, val sex: Char)
val user = User(99, "lisi", 'M')
//copy 函数
val(myID, myName, mySex) = user.copy()
println("myID:$myID, myName:$myName, mySex:$mySex")

5.6单例

kotlin中,object只实例一次,相当于单例

object MyEngine {

    fun m() {
        println("M run")
    }

    fun show() {
        println("我就只有一个实例")
    }
}

companion :意思是同伴对象。相当于java的static.

下面来看一下kotlin中的单例模式怎么写:

方式一:

class NetManager {

    // 只有一个实例
    object Holder {

        val instance = NetManager()

    }

    // 看不到 static  可以 派生操作
    companion object {

        // 全部都是  相当于 Java static

        fun getInstance() : NetManager = Holder.instance
    }

    fun show(name: String) {
        println("show:$name");
    }

}

方式二:

class NetManager2 {

    companion object {

        private var instance: NetManager2? = null

        // 返回值:允许你返回null
        fun getInstance(): NetManager2? {
            if (instance == null) {
                instance = NetManager2()
            }

            // 如果是null,也返回回去了
            return instance

            // 第二种补救: 我来负责 instance 肯定不为null
            // return instance!!
        }

    }


    fun show(name: String) {
        println("show:$name");
    }

}

5.7嵌套类

嵌套类,就是在类的内部又写了一个类,但是它不是内部类,拿不到外部类的成员。

class Sub {
    fun show() {
        println()
    }
    class A {
        class B {
            class C {
            }
        }
    }
}

5.8内部类

kotlin中,内部类用关键字inner来表示。

class Sub {
    fun show() {
        println()
    }
    class A {
        class B {
            class C {
            }
        }
    }
   }
    // 这个才是内部类
    inner class Sub2 {
        fun show() {
            println(I)
        }
    }
}


http://www.niftyadmin.cn/n/5032785.html

相关文章

竞赛 基于机器学习与大数据的糖尿病预测

文章目录 1 前言1 课题背景2 数据导入处理3 数据可视化分析4 特征选择4.1 通过相关性进行筛选4.2 多重共线性4.3 RFE&#xff08;递归特征消除法&#xff09;4.4 正则化 5 机器学习模型建立与评价5.1 评价方式的选择5.2 模型的建立与评价5.3 模型参数调优5.4 将调参过后的模型重…

Gin路由中间件详解

什么是中间件 Gin 中的中间件必须是一个 gin.HandlerFunc 类型,配置路由的时候可以传递多个 func 回调函 数, 最后一个 func 回调函数前面触发的方法 都可以称为中间件。 中间件操作演示 方法一: 直接写在func,回调函数内 r.GET("/middle",func(ctx *gin.Cont…

AlteraXilinx公司FPGA简介

Intel / Altera公司 Intel/Altera 系列FPGA简介 - 知乎 (zhihu.com) Altera FPGA 提供了多种可配置嵌入式 SRAM、高速收发器、高速 I/O、逻辑模块以及布线。其内置知识产权 (IP) 结合优秀的软件工具&#xff0c;缩短了 FPGA 开发时间&#xff0c;降低了功耗和成本。 Altera FP…

C++零碎记录(十三)

23. 多态 23.1 多态简介 ① 多态是C面向对象三大特性之一。 ② 多态分为两类&#xff1a; 1. 静态多态&#xff1a;函数重载和运算符重载属于静态多态&#xff0c;复用函数名。 2. 动态多态&#xff1a;派生类和 虚函数实现运行时多态。 ③ 静态多态和动态多态区别&#xff…

ElasticSearch(ES)简单介绍

ES简介 Elasticsearch&#xff08;通常简称为ES&#xff09;是一个开源的分布式搜索和分析引擎&#xff0c;旨在处理各种类型的数据&#xff0c;包括结构化、半结构化和非结构化数据。它最初是为全文搜索而设计的&#xff0c;但随着时间的推移&#xff0c;它已经演变成一个功能…

CentOS7下yum安装php7

1.安装epel-release EPEL&#xff08;Extra Packages for Enterprise Linux&#xff09;存储库提供了标准 Red Hat 和 CentOS 存储库中未包含的其他软件包。EPEL 存储库的创建是因为 Fedora 贡献者希望使用他们在 Red Hat Enterprise Linux&#xff08;RHEL&#xff09;及其衍…

【初阶数据结构】树(tree)的基本概念——C语言

目录 一、树&#xff08;tree&#xff09; 1.1树的概念及结构 1.2树的相关概念 1.3树的表示 1.4树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09; 二、二叉树的概念及结构 2.1二叉树的概念 2.2现实中真正的二叉树 2.3特殊的二叉树 2.4二叉树的性质…

C#实现钉钉自定义机器人发送群消息帮助类

一、自定义机器人发送群消息使用场景 在企业中,针对一些关键指标内容(如每天的生产产量、每天的设备报警信息等信息),需要同时给多人分享,此时就可以将需要查看这些数据的人员都拉到一个群中,让群里的机器人将这些关键指标内容推送到群里即可【(目前已实现在钉钉群里创建…