文章目录
-
-
- [1、安装 Java 和 Kotlin 环境](#1、安装 Java 和 Kotlin 环境)
- 2、程序代码基本结构
- 3、变量的声明与使用
- 4、数据类型
- 5、数字类型的运算
- [6、 选择结构](#6、 选择结构)
-
- 1)(if - else)(if - else))
- [2) 选择结构(when)------适用于多分支结构](#2) 选择结构(when)——适用于多分支结构)
- 7、循环结构
- 8、函数的定义及使用
- 9、类与对象
- 10、数组的创建与使用
- 11、集合类
-
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