Kotlin语法学习
创始人
2024-06-03 18:56:24
0

基础语法

基本函数定义

// 函数定义// 方式一// 基本语法:// 参数 -》 变量名:类型// 返回值类型 定义在方法后面 Int类型fun sum(a:Int, b:Int) : Int {return a+b;}// 方式二fun sum2(a:Int, b:Int) : Int = a+b// 返回类型可以不具体声明,即fun sum1(a:Int, b:Int) = a+b//使用public修饰就要显式声明返回类型public fun sum3(a:Int, b:Int) : Int = a+b//无返回值(类似java中的void)fun sum4(a:Int, b:Int) : Unit{println(a+b)}//使用public修饰可以省略返回类型,即fun sum5(a:Int, b:Int) : Unit{println(a+b)}

变长函数

//变长函数,使用vararg关键字标识fun vars(vararg v : Int) {for (vt in v) {print(v)}}//调用fun main(args: Array) {vars(1,2,3,4,5);}

lambda表达式

//lambda表达式val lambda:(Int, Int) -> Int = { x,y -> x+y }fun main(args: Array) {lambda(1,2);}

变量与常量定义

// 变量定义,可以不初始化// 语法: var [变量名]:[类型] = [初始值]var a:Int = 1; //初始化// 常量定义 相当于java中的final修饰,只能赋值一次// 可以不初始化// 语法: val [变量名]:[类型] = [初始值]val b:Int = 2; //初始化

字符串模板

//字符串模板// $表示一个变量名或变量值// $varname 表示变量值// ${varname.fun()} 表示变量的方法返回值var str1 = "xiaoming";val str = "hello, $str1";var str2 = "xiaohong";val str3 = "${str.replace("xiaoming", "$str2")}";

null 空检查机制

// null检查机制// 后面的? 表示arg的值可以为nullvar arg:String? = "23";//可抛出空指针异常, 使用!!表示当arg为空时,像java一样抛空指针异常var args = arg!!.toInt();//如果不做处理就返回nullvar args2 = arg?.toInt();// 做空判断,使用 ?: 判断,为空时,赋值-1返回var args3 = arg ?: -1;

类型检测与转换

//类型检测与转换// 使用 is 关键字来判断变量类型,类似于java中的instanceoffun getStringType(obj: Any) : Int ? {if (obj is String && obj.length > 0){ //&&左边的判断会将obj类型转换为Stringreturn obj.length;}return null;}

区间

// 区间// 语法: 变量名 in .. [步长可选]stepfun main(args: Array) {// [1, 4]输出1,2,3,4for(i in 1..4) {print(i)}// [1, 4]步长2,输出1,3for(i in 1..4 step 2) {print(i)}// [1, 4]步长2,输出42 downTo倒序for(i in 4 downTo 1 step 2) {print(i)}// [1, 4)for (i in 1 until 4) {print(i)}}

基本数据类型

在这里插入图片描述

数字比较

=== 表示比较两个对象地址
== 表示比较两个数值大小

类型转换

较小类型的不能直接赋值给较大类型,如Byte类型不能直接赋值给Int类型
可以使用kotlin自带的函数进行转换:
toInt() 转换为Int类型
toDouble 转换为Double类型

位操作符

# 对于long和int类型适用
shl(bits) – 左移位 (Java’s <<)
shr(bits) – 右移位 (Java’s >>)
ushr(bits) – 无符号右移位 (Java’s >>>)
and(bits) – 与
or(bits) – 或
xor(bits) – 异或
inv() – 反向

字符Char

和 Java 不一样,Kotlin 中的 Char 不能直接和数字操作,Char 必需是单引号 ’ 包含起来的。比如普通字符 ‘0’,‘a’。

布尔Boolean

值:true 或 false
运算:||、&&、!

数组

// 数组fun main(args: Array) {//创建数组方式一 arrayOf()// [1, 2, 3]val a = arrayOf(1,2,3);//方式二 Array// [0, 2, 4]val b = Array(3, {i -> (i*1)})// 数组长度print(a.size);// get/set => []重载了get/set方法print(b[0])//ByteArray, ShortArray, IntArrayval c = IntArray(3, {i -> (i+1)})}

字符串

fun main(args: Array) {// 字符串 不可变// 可以使用for循环遍历字符串var str = "1234";for (c in str) {print(c)}//多行// trimIndent 删除多余空格val text = """多行字符串多行字符串""".trimIndent()//trimMargin 可以指定删除的字符val text1 = """|多行字符串|多行字符串""".trimMargin("|")}

条件控制

if…else

// 传统用法
val max1:Int
if(a>b) {max1 = a
} else {max1 = b
}// 表达式用法
val max = if(a>b) a else b

when

//类似其他语言的 switch 操作符,else类似于 default
when (x) {1 -> print("x == 1")2 -> print("x == 2")else -> { // 注意这个块print("x 不是 1 ,也不是 2")}
}

循环控制

for

// for// 可以遍历任何迭代器fun main(args: Array) {val ints = Array(3, {i -> (i+1)})for (item:Int in ints) {print(item)}// 通过索引遍历一个数组或者一个 listfor (i in ints.indices) {print(ints[i])}// 或for ((index, value) in ints.withIndex()) {print("the element in $index is $value")}}

while

while( 布尔表达式 ) {//循环内容
}

do … while

与while不一样在于,do…while至少会执行一次

do {//代码语句
}while(布尔表达式);

break 和 continue

fun main(args: Array) {for (i in 1..10) {if (i==3) continue  // i 为 3 时跳过当前循环,继续下一次循环println(i)if (i>5) break   // i 为 6 时 跳出循环}
}

标签处返回

任何表达式都可以用标签(label)来标记。 标签的格式为标识符后跟 @ 符号,例如:abc@、fooBar@都是有效的标签。 要为一个表达式加标签,我们只要在其前加标签即可。

loop@ for (i in 1..100) {// ……
}loop@ for (i in 1..100) {for (j in 1..100) {if (……) break@loop}
}

标签限制的 break 跳转到刚好位于该标签指定的循环后面的执行点。 continue 继续标签指定的循环的下一次迭代。

类和对象

//类和对象class Person() {// 成员函数fun sayHi(){print("hello");}// 类属性var age : String = "12";var name : String = "小明";//getter settervar sex : Int = 0get() = field // field为后端变量关键字set//类中的非空属性必须初始化,可以使用lateinit关键字延迟初始化lateinit var subject:TestSubjectfun setup() {subject = TestSubject();}fun test() {subject.method();}}//空类class Empty;class TestSubject(){fun method(){print("subject test")}}// 主构造器// 主构造器中不能包含任何代码,初始化代码可以放在初始化代码段中,初始化代码段使用 init 关键字作为前缀class Student constructor(name:String) {init {print("name is $name")}//次构造器constructor(name: String, age: Int) : this(name) {// 初始化}}// 抽象类//抽象是面向对象编程的特征之一,类本身,或类中的部分成员,都可以声明为abstract的。抽象成员在类中不存在具体的实现。//注意:无需对抽象类或抽象成员标注open注解。open class Base{open fun f() {}}abstract class Deeived: Base() {override abstract fun f()}//嵌套类class Outer{ //外部类private val bar:Int = 1;var v ="成员属性";class Nested { // 嵌套类fun foo() = 2}// 内部类inner class Inner {fun foo1() = bar //可以访问外部类成员fun test(){var o = this@Outer; //获取外部类成员变量print(o.v);}}//匿名内部类fun setInterFace(test: TestInterFace) {test.test()}}//接口定义interface TestInterFace {fun test()}fun main(args:Array) {//实例化val student = Person();//访问属性print("name is" + student.name+",age=" +student.age);// 调用嵌套类val demo = Outer.Nested().foo();// 采用对象表达式来创建接口对象,即匿名内部类的实例var test = Outer();test.setInterFace(object:TestInterFace{override fun test() {TODO("Not yet implemented")}})}

** 类修饰符**

abstract    // 抽象类  
final       // 类不可继承,默认属性
enum        // 枚举类
open        // 类可继承,类默认是final的
annotation  // 注解类

访问权限修饰符

private    // 仅在同一个文件中可见
protected  // 同一个文件中或子类可见
public     // 所有调用的地方都可见
internal   // 同一个模块中可见

继承

Kotlin中所有类都继承Any类,Any类默认提供三个函数:
equals()
hashCode()
toString()

注意:Any类和java.lang.Object不一样

如果一个类需要被继承,用open关键字修饰

构造函数

// 子类有构造函数,则基类必须在主构造函数中立即初始化
open class Person(var name : String, var age : Int){// 基类}class Student(name : String, age : Int, var no : String, var score : Int) : Person(name, age) {}//子类没有构造函数
//则必须在每一个二级构造函数中用 super 关键字初始化基类,或者在代理另一个构造函数。初始化基类时,可以调用基类的不同构造方法
class Student2 : Person {constructor(ctx: Context) : super(ctx) {} constructor(ctx: Context, attrs: AttributeSet) : super(ctx,attrs) {}
}// 测试
fun main(args: Array) {val s =  Student("Runoob", 18, "S12346", 89)println("学生名: ${s.name}")println("年龄: ${s.age}")println("学生号: ${s.no}")println("成绩: ${s.score}")
}

重写

fun默认被final修饰,不可重写,如果要可被重写,需要用open关键字修饰,使用override关键字重写方法

属性重写

使用override关键字

接口

使用 interface 关键字定义接口,允许方法有默认实现

// 同一方法继承多个实现
//接口中的属性只能是抽象的,不允许初始化值,接口不会保存属性值,实现接口时,必须重写属性
interface A {var name:String //name 属性, 抽象的fun foo() { print("A") }   // 已实现fun bar()                  // 未实现,没有方法体,是抽象的
}interface B {fun foo() { print("B") }   // 已实现fun bar() { print("bar") } // 已实现
}class C : A {override var name: String = "runoob" //重写属性override fun bar() { print("bar") }   // 重写
}class D : A, B {override var name: String = "runoob" //重写属性override fun foo() {super.foo()super.foo()}override fun bar() {super.bar()}
}fun main(args: Array) {val d =  D()d.foo();d.bar();
}

泛型

// 声明一个泛型类
class Box(t: T) {var value = t
}//使用
val box: Box = Box(1)
// 或者
val box = Box(1) // 编译器会进行类型推断,1 类型 Int,所以编译器知道我们说的是 Box

枚举

enum class Color{RED,BLACK,BLUE,GREEN,WHITE
}

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
带头循环双向链表来咯!!! 前言:继上文,我们了解了结构最简单的一种链表---单链表那么我们今天就来...