kotlin 基础

文章目录

1、安装 Java 和 Kotlin 环境

2、程序代码基本结构

java 复制代码
fun main(args: Array<String>) {
    println("Hello World!")
}
  • 注意点:Kotlin 严格区分大小写

3、变量的声明与使用

java 复制代码
fun main(args: Array<String>) {
    var x = 30
    println(x)
}

// 自动判断变量类型
fun main(args: Array<String>) {
    var x = 30
    println(x)
}

// 变量值赋值给变量
fun main(args: Array<String>) {
    var x = 30
    var y = x
    println(y)
}

fun main(args: Array<String>) {
    var x = 30
    var y = x / 30
    println(y)
}

fun main(args: Array<String>) {
    var x = 30
    var y = 70
    println(x + y)
}

fun main(args: Array<String>) {
    var x = 30
    x = 20
    println(x)
}

// 定义常量
fun main(args: Array<String>) {
    val x = 30  // 常量
    println(x)
}

4、数据类型

  • Byte、Short、Int、Long
  • Float、Double
java 复制代码
val pi = 3.1415 // 默认推断为 Double 类型
val one : Double = 1  // 这种写法错误,无法编译通过
val one : Double = 1.0 // 这种写法是对的
val a : Float = 1.0f
  • 与其他语言不同,Kotlin 中的数字类型没有隐式转换的操作
java 复制代码
var a:Int = 1;
var b:Double = a;  // 报错,不能隐式转换

5、数字类型的运算

1)布尔类型
java 复制代码
var a: Boolean = false
2)字符类型
java 复制代码
var c: Char = 'D'
3)字符串类型
java 复制代码
    // 字符串中的字符一旦确定是无法进行修改的
    var str: String = "Hello World"
    str = "Helle World"  // 整体修改
    
    val text = "Hello\nWorld"  // 字符串中换行,需要用到转义字符		      

6、 选择结构

1)(if - else)
java 复制代码
if 
if {

}

if {
} else {
}

if
else if 
else if 
else 

if {

    if 

}

// if-else 还可以用作结果判断
var score = 2
var res = if (score > 60) "Yes" else "NO"
2) 选择结构(when)------适用于多分支结构
java 复制代码
//代码结构
when (目标) {
    匹配值1 -> 代码
    匹配值2 -> 代码
    匹配值3 -> 代码
    else -> {  // 可以没有else语句,类似于之前的 if-else if-else
        代码  // 如果以上条件都不满足,就进入else中
    }
}
java 复制代码
val c = 'A'
when (c) {
    'A' -> println("尖子班")
    'B' -> println("中等班")
    'C' -> println("普通班")
}

val c = 'A'
var value = when (c) {
    'A' -> 1
    'B' -> 2
    'C' -> 3
    else -> 0  // 要把所有能表示的情况都写完才不会报错(必加)
}

val c : Boolean = true
var value = when (c) {
    true -> 1
    false -> 2  
    // 所有情况中只有这两种情况所以不用加else 
}

// 某些值属于同一种情况,可以使用逗号将其条件组成一行
var x = 0;
when (x) {
    0, 1 -> print("x == 0 or x == 1")
    else -> print("otherwise")
}

// in 表示区间
var score = 10;
var grade= when (score) {
    // 使用 in 判断目标标量值是否在指定范围
    in 100 .. 90 -> {
        println();
        "优秀"
    }
    in 89 .. 80 -> "良好"
    in 79 .. 70 -> "及格"
    else -> "不及格"
}

7、循环结构

1)for
java 复制代码
// 结构
for (遍历出来的单个目标 in 可遍历目标) 循环体
  • 可遍历目标
    • 数组
    • 区间
    • 任何实现了运算符重载函数iterator的类
java 复制代码
// 可遍历目标为区间
for (i in 1..3)
    println(i)

val range: IntRange = 1..3
for (i in range)
    println(i)


val range: IntRange = 1..3
var x = 0
for (i in range) {  // i 的作用范围只在括号中
    println(i)
    x = i
}
java 复制代码
// for 循环的嵌套
for (i in 0..2) {
    for (j in 0..2) {
        println("外层 $i,内层$j")
    }
}
2)循环结构------while
java 复制代码
while (循环条件) 循环体

8、函数的定义及使用

1)用 fun 关键字声明
kotlin 复制代码
fun 函数名称([函数参数...]): 返回类型 {
    // 函数体
}
kotlin 复制代码
// 无返回值的两种写法
fun test(): Unit {  // 返回值类型为Unit类比于其他语言中的void
    
}

fun text() {
    
}
2)函数的调用
kotlin 复制代码
fun main() {
    test()
}
3)有参数的函数
kotlin 复制代码
fun text(m: String) {  // m为参数名字,String为参数类型
    println(m)
}
4)有返回值的函数
kotlin 复制代码
fun text(a: Int, b: Int) : Int{  // a,b为参数,Int 为返回值类型
    return a + b
}


// return 关键字在执行之后,后面的内容就不能继续执行了
fun text(a: Int, b: Int) : Int{  // a,b为参数,Int 为返回值类型
    if (a + b > 10) 
        return 10
    println("后面的函数")
    return a + b
}


fun main(args: Array<String>) {
    test()  // 参数有默认值之后可以不传入实参
}   
fun test(m: String = "HelloWorld") {
    println(m)
}


fun main(args: Array<String>) {
    test("Hi")  // 传入值则形参为传入的值
}
fun test(m: String = "HelloWorld") {
    println(m)
}


fun sum(a: Int, b: Int): Int = a + b
fun sum(a: Int, b: Int) = a + b
5)全局变量
java 复制代码
var a: Int = 10

fun main(args: Array<String>) {
    println(a)
}

fun test() {
    a = 20
    println(a)
}
java 复制代码
var a: Int = 5
    get() = field + 10  // field代表变量a本身

fun main(args: Array<String>) {
    println(a)  // 此时打印出来的是15
}

fun test() {
    a = 20
    println(a)
}
java 复制代码
// 变脸中get和set属性
// get 和 set 函数操作的就是本身变量的值
var a: Int = 5
    get() = field + 10  // field代表变量a本身
    set(value) {  // value是赋值过来的参数
        println("我被赋值了")
        field = value
    }

fun main(args: Array<String>) {
    a = 90
    println(a)  // 此时打印出来的是15
}
6)函数类型变量
1 变量可以接收函数
java 复制代码
// 接收String作为参数返回值为Int的函数类型
    var func: (String) -> Int   // (String) -> Int:String作为参数,返回值为Int的函数给变量func存储
2 函数也可以接收函数
java 复制代码
fun test(func: (String) -> Int) {  // 形参可以为函数类型的参数

}

fun test(other: (Int) -> String) {
    println(other(1))  // 
}
3 总结
  • 函数类型的变量可以当作函数使用
  • 函数类型的变量也可以作为函数参数进行传递

9、类与对象

  • 类是一个抽象的概念,对象指具体的
1) 类的定义与对象的创建
  • 类的声明使用关键字 class 声明
kotlin 复制代码
class Student {
}
  • kotlin 中的类可以添加一个主构造函数和一个或多个次要构造函数,主构造函数是类定义的一部分
kotlin 复制代码
class Student constructor(name: String, age: Int) {  // 主构造函数的形参

}

// 主构造函数中的constructor也可以省去
class Student (name: String, age: Int) {

}

// 将构造函数的 参数变成类的属性,在变量前面添加 var或者 val
class Student (var name: String, var age: Int) {

}

// 属性写在类里面的时候,必须要求有初始值
class Student () {
    var name: String = ""
    val age: Int = 8
}


class Student (name: String, age: Int) {  // 将传进来的参数赋值给属性
    var name: String = name
    val age: Int = age
}
2) 对象的创建
  • 对象的创建就是通过构造函数,调用构造函数
kotlin 复制代码
// 引用赋值
fun main(args: Array<String>) {
    var p1 = Student("小明", 18)
    var p2 = p1  // 引用赋值,指向的是同一个对象
    println(p2.name)  // p2也就可以操控对象
}


fun main(args: Array<String>) {
    var p1 = Student("小明", 18)  // 通过构造函数创建对象
    var p2 = p1  // 引用赋值
    println(p2 == p1)  // 判断p1和p2是否指向的是同一个对象,输出结果为true
}

fun main(args: Array<String>) {
    var p1 = Student("小明", 18)
    var p2 = Student("小红", 19)
    println(p2 == p1)  // p1和p2指向的是两个不同的对象,输出结果为false
}
                                         
fun main(args: Array<String>) {
    var p1 = Student("小明", 18)
    var p2 = Student("小明", 18)
    println(p2 == p1)  // 输出为false,通过构造函数创建出来的就是一个独立的对象
}

class Student (name: String, a	ge: Int) {  // 将传进来的参数赋值给属性
    var name: String = name
	val age: Int = age
}           
3)对象的初始化
  • 在对象创建时,我们可能需要做一些初始化工作,可以使用初始化代码块来完成,初始化代码块使用init关键字来完成,Init 函数在创建对象的时候会自动执行;
  • 例如,我们希望对象在创建时,如果年龄不足18岁,那么就设定为18岁
  • 这样在创建对象的时候,就会在创建的时候自动执行初始化代码块里面的代码了
kotlin 复制代码
fun main(args: Array<String>) {
    var stu = Student("小明", 9)

}

        class Student (var name: String, var age: Int) {
    // 可以定义多个init,执行顺序为从上往下依次执行
    init {
        println("我是初始化操作")
        if (age < 18) age = 18
        println(age)
        println("初始化操作结束")
    }

    init {
        
    }
}
4)类的成员函数
  • 如果函数中的变量存在歧义,那么优先使用作用于最近的一个,比如函数形参的 name 作用域更近,那么这里的 name 拿到的一个是形参 name,而不是类的成员属性 name
  • 如果我们要获取的是类中的成员属性,需要使用 this 关键字来表示当前类
  • 默认情况下,如果作用域不冲突,使用类中属性 this 可以省略
kotlin 复制代码
fun main(args: Array<String>) {
   var stu = Student("小明", 19)
    stu.hello()
}

class Student (var name: String, var age: Int) {
    fun hello() {
        println("大家好啊")
    }
}

                      
// 默认变量指代的就是离它最近的
class Student (var name: String, var age: Int) {
    fun hello(name: String) {
        println("大家好啊,我叫$name")  // 指代的是hello中的参数name
        // 使用 this 关键字表示当前对象,这样就可以指定这里是类中this中的name 属性了
        println("大家好啊,我叫${this.name}") // 指代的是类中属性name
    }
}

在类中,同样可以定义多个同名但是不同参数的函数实现重载

kotlin 复制代码
class Student(var name: String, var age: Int) {
    fun hello() = println("大家好,我叫 ${this.name},今年${age}岁")
    fun hello(gender: String) = println("大家好,我叫 ${this.name},今年 ${age} 岁,性别 ${gender}")
}
5) 再谈基本类型
  • Kotlin 中万物皆对象,所有变量存储的都是对象的引用
kotlin 复制代码
fun main(args: Array<String>) {
    val a: Int = 10  // Int类型的对象,值为10,而a持有的是对这个Int对象的引用
    val b: Double = a.toDouble()
}
kotlin 复制代码
fun main(args: Array<String>) {
    val a: Int = 10  // Int类型的对象,值为10,而a持有的是对这个Int对象的引用
    val b: Int = 5
    val c: Double = b / a.toDouble()  // 结果为0.5
}

fun main(args: Array<String>) {
    val str: String = "10"
    str.length()
    str.toInt()
}
a、空值和空类型
  • 所有的变量除了引用一个具体的值以外,还有一种特殊的值可以使用,就是 null,它代表空值,即不引用任何对象
  • 所有的类型默认都是非空类型,非空类型的变量是不允许被赋值为 null,这直接在编译阶段就避免了其他语言中经常存在的空指针问题
kotlin 复制代码
fun main(args: Array<String>) {
    val stu: Student = null //报错
}
  • 希望某个变量在初始化情况下使用 null,而不是去引用某个具体的对象,将变量的类型修改为可空类型,只需要再类型名的后面添加一个 ? 即可
kotlin 复制代码
val stu: Student? = null // 正确,加了?号之后就可以为空了,不代表任何对象
6)修饰符
  • private、internal、public
7)封装
kotlin 复制代码
class Student(private var name: String, private var age: Int) {
    fun getName(): String = name
    fun getAge(): Int = age
    fun setName(name: String) {
        if (name.contains("刚")) return
    	this.name = name
	}
}	
8)继承
  • Kotlin 中类是 终态的(不能被任何类继承),要使类可继承,需要用关键字 open 标记需要被继承的类
kotlin 复制代码
open class Student { // 可以被继承,可作为父类

}

class ArtStudent: Student() {  // 以调用主构造函数的形式进行声明,这个类就是Student的子类

}
  • 当一个类继承另一个类时,属性会被继承,可以直接访问父类中定义的属性,除非父类中将属性的访问权限修改为 private,那么子类将无法访问
kotlin 复制代码
open class Student { // 可以被继承,可作为父类
    var name: String = "小明"
    fun hello() = println("大家好,我叫 $name")
}

class ArtStudent: Student() {  // 以调用主构造函数的形式进行声明,这个类就是Student的子类
    fun test() {
        name  // 可以直接访问父类中的属性
        hello()  // 可以直接访问父类中的方法
    }
}
9)属性的覆盖------多态
  • 子类重写父类定义的内容
  • 有些时候,我们可以子类继承父类的某些属性,,但是我们可能希望去修改这些属性的默认实现,可以使用 override 关键字来表示对一个属性的重写(覆盖)
kotlin 复制代码
fun main() {
    var student = ArtStudent()
    student.hello()
	}


open class Student { // 可以被继承,可作为父类
    open fun hello() = println("我会打招呼")
}

class ArtStudent: Student() {  // 以调用主构造函数的形式进行声明,这个类就是Student的子类
    fun draw() = println("我会画画")
    override fun hello() {
        // 在子类中编写一个同名函数,并添加override关键字,就可以在子类中进行覆盖了,然后编写自己的实现
        println("我会画画")
        super.hello()  // 可以执行父类的
    }
}

class MusicStudent: Student() {
    override fun hello() = println("我会唱歌")
}
10)接口
  • 定义一些所具备的功能
kotlin 复制代码
interface A {
    val x: String // 接口中所有属性默认都是abstract的(所以可省略abstract关键字)
    fun sleep()  // 接口中所有函数默认都是abstract的(所以可省略abstract关键字)
}

interface B {
    fun game()
}

// 用类去实现接口中的功能
// Student 实现了A和B接口,证明同时具有了A和B中的功能
class Student: A, B {  // 接口的实现和类的继承一样,直接写到后面,多个接口用逗号隔开
    override val x: String = "测试"  // 跟抽象类一样,接口中的内容是必须要实现的
    override fun game() = println("玩游戏")

    override fun sleep()  = println("睡觉")
}

10、数组的创建与使用

  • 存放一组相同类型的数据
  • 在kotlin中,数组是Array类型的对象
  • 在 Kotlin 中创建数组有两种创建方式:1)官方预设工具函数:arrayOf()、arrayOfNulls() 以及 emptyArray()
  • 使用类 Array 构造函数创建
kotlin 复制代码
val array: Array<Int> = arrayOf(7, 3, 9, 1, 6)  // 直接在arrayOf函数中添加每个元素
  • 注意:数组在创建完成后,数组容量和元素类型是固定不变的,后续无法进行修改

  • 数组元素的访问和修改

kotlin 复制代码
val array: Array<Int> = arrayOf(7, 3, 9, 1, 6)  // 直接在arrayOf函数中添加每个元素
println(array[0])
array[0] = 2

val array: Array<Int> = arrayOf(7, 3, 9, 1, 6)  // 直接在arrayOf函数中添加每个元素
for (i in 0 until array.size) {  // 方式1
    println(array[i])
}

for (element in array) {  // 方式2
    println(element)
}
  • 数组中的操作
kotlin 复制代码
val array1: Array<Int> = arrayOf(1, 2, 3, 4, 5)
val array2: Array<Int> = arrayOf(1, 2, 3, 4, 5)
val array3 = array1

println(array1 == array2)  // 结果为false,比较是否是两个同一个对象
println(array1 == array3)  // 结果为true,因为比较的是两个相同的对象

// 比较两个数组中的内容是否相同
println(array1.contentEquals(array2))  // 结果为true,两者内容相同

11、集合类

1)数组局限性
  • 长度是固定的,无法扩展 ;
  • 无法做到在数组中像列表那样进行插入和删除元素;
2)集合的分类
  • List:有序的集合,通过索引访问元素,可以包含重复元素
  • Set:不包含重复元素的集合,一般情况下不维护元素顺序
  • Map:是一组键值对,其中每个键不可重复存在,每个键都映射到恰好一个值(值可以重复存在)
  • 所有集合类都是继承自 Collection 接口(Map 除外)
3)集合简介
  • List:可以自由地在某个位置插入或删除一个元素,列表的长度也会动态发生变化
kotlin 复制代码
// 创建一个 list
    val list: MutableList<Int> = mutableListOf(1, 2, 3, 4, 5)  // 创建可变集合
    // 支持所有数组的操作
	list[0] = 10
    println(list)  // 格式化地打印
    println(list.get(1))  // 取数据
    list.add(9)  // 在末尾添加一个新元素
    list.add(1, 10)  // 在下标为1处,添加元素10,可插入范围只能是[0, size]这个闭区间内
  • Set 集合
kotlin 复制代码
// 创建一个Set集合
val set: Set<String> = mutableSetOf("AA", "BB", "BB", "CC")
println(set)  // 因为set中不允许出现重复元素,结果为 [AA, BB, CC]
  • Map
kotlin 复制代码
// 创建一个 Map
val map: MutableMap<Int, Student> = mutableMapOf(
    10001 to Student("小明", 18),
    10002 to Student("小红", 17),
    10003 ti Student("小刚", 16)
)
kotlin 复制代码
val student: Student? = map[10001]  // 使用[]运算符通过Key查找value
val student1: Student? = map[10001]  // 得到小明这个对象
val student2: Student? = map[10005]  // Map 中根本没有键为10005的键值对,所以得到结果为null
kotlin 复制代码
map.contains(1)  // 判断是否包含指定Key
map.containKey(1)  // 同上
10001 in map  // 同上

map.containsValue(Student("小明", 18))  // 判断是否包含Value
kotlin 复制代码
val keys: MutableSet<Int> = map.keys   //以Set形式存储的[10001, 10002, 10003]
val value: Collection<Student> = map.values 
相关推荐
猷咪7 分钟前
C++基础
开发语言·c++
IT·小灰灰8 分钟前
30行PHP,利用硅基流动API,网页客服瞬间上线
开发语言·人工智能·aigc·php
快点好好学习吧10 分钟前
phpize 依赖 php-config 获取 PHP 信息的庖丁解牛
android·开发语言·php
秦老师Q10 分钟前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
烟锁池塘柳011 分钟前
解决Google Scholar “We‘re sorry... but your computer or network may be sending automated queries.”的问题
开发语言
是誰萆微了承諾11 分钟前
php 对接deepseek
android·开发语言·php
2601_9498683615 分钟前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter
星火开发设计28 分钟前
类型别名 typedef:让复杂类型更简洁
开发语言·c++·学习·算法·函数·知识
qq_1777673740 分钟前
React Native鸿蒙跨平台数据使用监控应用技术,通过setInterval每5秒更新一次数据使用情况和套餐使用情况,模拟了真实应用中的数据监控场景
开发语言·前端·javascript·react native·react.js·ecmascript·harmonyos
一匹电信狗42 分钟前
【LeetCode_21】合并两个有序链表
c语言·开发语言·数据结构·c++·算法·leetcode·stl