Kotlin基础教程

内容目录

前言

Kotlin 是一个静态类型的语言, 运行于JVM虚拟机之上,但是Kotlin还有
kotlin/native(windows, linux, macos, ios, android, webAsm)kotlin/jskotlin/server-side

但是除了JVM平台之外其他的平台都很少用, 本篇文章以JVM平台为教程

题外话

java的构件包是.jar, 而Kotlin KMP(Kotlin MultiPlatform)的包是.klib的, 虽然也可以发布到maven中央仓库中, 但是还是要提一下

kotlin

main方法

main方法就是一个程序的入口点所有的代码都从这里执行,跟Java中的main方法不同的是
Kotlin中的main方法是一个top-level 顶层函数 而Java中的main方法是写在一个
看下面的示例

fun main() {
    TODO("程序的入口点")
}

如果你想像Java那样将main方法写入类中则需要借助伴生对象@JvmStatic注解来实现

class MyApp {
    companion object {
        @JvmStatic
        fun main(args: Array<String>) {
            TODO("程序的入口点")
        }
    }
}

如果你不懂的话没关系因为这是在后面才会学到

TODO是一个Kotlin内置的函数用于表示一处代码未完成, 如果一段代码执行刀TODO之后
就会抛出NotImplementedError异常

基本类型

这里先给出基本类型占用内存空间大小的表格

类型 长度(单位:字节) 表示范围
Byte 1 -128 到 127
UByte 1 0 到 255
Short 2 -32,768 到 32,767
UShort 2 0 到 65,535
Int 4 -2.15 × 10⁹ 到 2.15 × 10⁹
UInt 4 0 到 4,294,967,295
Long 8 -9.22 × 10¹⁸ 到 9.22 × 10¹⁸
ULong 8 0 到 18,446,744,073,709,551,615
Float 4 -3.40 × 10³⁸ 到 3.40 × 10³⁸
Double 8 -1.80 × 10³⁰ 到 1.80 × 10³⁰
Char 2 0 到 6.55 × 10⁴
Boolean 1 truefalse

基本类型就是一个语言内置的类型, 例如整形、 长整型、字符串等等

字符串

在Kotlin中定义一个字符串很简单只需要用"包裹起来就是一个合法的字符串, 就像下面这样

val string = "This is a string"

注意Kotlin跟Python的字符串不同的点是Kotlin中的字符串全都是双引号, 用单引号
包裹的是字符只能包含一个字符(可以是中文), 具体看下面的示例

字符

Kotlin中的字符是使用单引号包裹起来的就像下面这样

val char = 'A'
val char2 = '我'

数值

整形Int

整形Int是一个常规的数字任何不加特殊标识的数字都是整形Int, Int占用的内存空间是4个字节
像下面这样定义一个整形

val intVar = 1

无符号整形UInt

只需要在数字后面加上一个Uu就能表示了

val uintVar = 1u

长整型Long

在数字后加上一个Ll, 就像下面这样

val longVar = 1L

无符号长整型

在长整型的技术上加上类型ULong

val ulong: ULong = 114514L 

Short

只能使用类型标注的方法定义一个Short类型的数字

val short: Short = 1

单精度浮点

val float = 1f

双精度浮点

val double = 1.0

特殊类型

字节Byte

这个类型需要使用0x或者0b来表示

16进制

16进制使用0x开头的数字来表示

val hex = 0x114514

8进制

由于Kotlin目前并不支持直接表示8进制的数据所以需要使用Integer.parseInt("10", 8)来表示

val octal = Integer.parseInt("10", 8)

2进制

2进制需要使用0b表示

val binary = 0b11

基本语法

注释

注释使用双斜杠或者块状注释的写法像下面这样

/**
 * 这是一大段文档
 */
fun main() {
    // 这是一行注释
}

变量

定义一个变量需要使用valvar来表示, val是不可变的,var是可变的,
意思就是val声明之后就不能改变他的值了, var声明之后可以改变这个变量的值
但是需要类型相同

val exampleString = "这里是一个变量"

函数

定义函数需要使用fun关键字, 然后加上形参和类型, 文章开始的main方法就是一个函数
他接收一个Array<String>的参数,当然这个参数是由Jvm来传递的这个数组的内容就是运行Jar之后
传递的参数用空格区分, 现在定义一个不带参数的函数,并且没有返回值

fun example() {
}

现在定义一个带参数但是不带返回值的函数

fun example(name: String) {
}

现在定义一个带参数带有返回值的函数

fun example(name: String): String {
    return "Hello $name"
}

这里使用到了字符串插值的语法, 使用$符号后面街上变量名或者大括号,打括号内可以是一个语句

Kotlin中的类有很多中, 最基本也是最常用的类就是一个class修饰的类

基本类

class Hello

这就定义了一个最基本的类, 它不包含任何构造器

现在写一个带有主构造器的类

class Hello(name: String)

当然这个类并没有任何实际的行为, 你可以按照下面的方式创建这个类的对象

fun main() {
    Hello("John")
}

现在给一个类添加一个行为(方法)

class Hello(name: String) {
    fun greet() {
        println(name)
    }
}

当然如果你这样定义的话会报错, 因为name没有被声明
你可以选择一下两种方式来声明这个name

class Hello(name: String) {
    val name = name
    fun greet() {
        println(name)
    }
} 
class Hello(val name: String) {
    fun greet() {
        println(name)
    }
}

不推荐第一种方式因为这样对我们的手指很不友好, 第二种方式是在主构造器构造的时候就直接声明
这个变量, 如果你有Java基础的话就能明白

现在来给这个类加上属性吧

class Hello(val name: String) {
    val age = 18
    fun greet() {
        println("你好我叫: $name, 我现在${age}岁")
    }
}

抽象类

抽象类主要用于OOP(面向对象)编程, 抽象类本身不能直接被创建需要一个子类继承
抽象类然后创建子类的对象, 就像下面这样

abstract class Parent

class Child: Parent()

抽象类中可以包含以下成员

  1. 普通函数
  2. 抽象函数
  3. 普通变量
  4. 抽象变量

所有的抽象成员都不能在抽象类中被赋值,如果一个方法或者属性不是抽象的话
则必须在抽象类中完成赋值,非抽象方法必须有实现(有函数体), 如果是抽象方法
或者抽象属性的话就必须由子类继承后子类重写这个方法/属性然后赋值,
就像下面这样

abstract class Parent {
    val name = "John"
    abstract val age: Int

    fun eat() {
        println("我正在吃...")
    }

    abstract fun greet()
}

class Child : Parent() {
    override val age = 18

    override fun greet() {
        println("你好我叫: $name, 我今年: ${age}岁")
        this.eat()  // 这里调用了父类的已有实现
    }
}

抽象类也可以有构造器但是有构造器并不意味着能直接创建抽象类还是需要子类继承后在
添加构造器参数就像下面这样

abstract class Parent(val sex: Boolean) {
    val name = "John"
    abstract val age: Int

    fun eat() {
        println("我正在吃...")
    }

    abstract fun greet()
}

class Child : Parent(true) {
    override val age = 18

    override fun greet() {
        println("你好我叫: $name, 我今年: ${age}岁")
        this.eat()  // 这里调用了父类的已有实现
    }
}

数据类

数据类本质上跟常规类区别并不大, 主要就是有以下几点

  1. 只能有一个构造器
  2. 不能被继承
  3. 数据类在编译的时候会自动生成代码

创建一个数据类需要使用data class关键字修饰, 然后在主构造器内
放入需要的参数

data class Son(val nane: String, val age: Int)

Kotlin编译器会自动的生成componentX()方法用于拆包(解构)、toString()方法
用于格式化字符串输出、hashCode()方法用于生成数据类的哈希码、equals()方法用于比较两个对象
是否相同、copy()方法用于直接复制一个对象以及所有字段的getter/setter(因为在Java中
没办法直接访问一个类中的变量需要手动写一个getter方法来获取这个变量, 写一个setter来设置这个变量)

然后就是拆包, 拆包就是在一行中快速的将变量拆出并赋值

fun main() {
    val son = Son("John", 18)
    val (name, age) = son
}

值类

值类很少用,也可以跳过这部分不看,值类的特点有以下几点

  1. 只能有一个参数
  2. 必须是val
  3. 必须是inline(内联)

创建一个值类

@JvmInline
value class Email(val email: String)

单例类

单例类就是全局只存在这一个对象, 并且不需要创建对象就可以访问变量, 类似于Python的全局变量

object Person {
    val name = "John"
    val age = 18
}

fun main() {
    println(Person.name)
}

接口

定义一个接口使用interface关键字修饰, 接口内所有的变量、方法都是abstract抽象的
但是也能有默认实现, 跟抽象类差不过但是不能有构造器,然后类要继承也不叫继承实现

interface Bot {
   val host: String

    fun say() {
        println("hello")
    }

    fun eat()
}

class FancyBot: Bot {
    override val host: String
        get() = TODO("Not yet implemented")

    override fun eat() {
        TODO("Not yet implemented")
    }
}

实现接口不需要加上()

温馨提示:

1.本站大部分内容均收集于网络!若内容若侵犯到您的权益,请发送邮件至:[email protected],工作室将第一时间处理!

2.资源所需价格并非资源售卖价格,是收集、整理、编辑详情以及本站运营的适当补贴,并且本站不提供任何免费技术支持。

3.所有资源仅限于参考和学习,版权归原作者所有。

KotlinLanguage学习技术默认

Kotlin中操作二进制数据

2025-1-4 14:34:27

默认

记录一下使用Compose multiplatform for web的使用

2025-3-11 22:29:12

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索