Kotlin 基础教程
Kotlin 文件以 .kt 为后缀
一、基本语法
package hello
class Test {
fun main(args: Array<String>) {
// 1. 定义常量与变量
val a: Int = 1
val b = 1 // 系统自动推断变量类型为Int
val c: Int // 如果不在声明时初始化则必须提供变量类型
c = 1 // 明确赋值
var x = 5 // 系统自动推断变量类型为Int
x += 1 // 变量可修改
// lambda(匿名函数)
val sumLambda: (Int, Int) -> Int = {x,y -> x+y}
println(sumLambda(1,2)) // 输出 3
// 字符串模板
var a = 1
// 模板中的简单名称:
val s1 = "a is $a"
a = 2
// 模板中的任意表达式:
val s2 = "${s1.replace("is", "was")}, but now is $a"
// NULL检查机制
//类型后面加?表示可为空
var age: String? = "23"
//抛出空指针异常
val ages = age!!.toInt()
//不做处理返回 null
val ages1 = age?.toInt()
//age为空返回-1
val ages2 = age?.toInt() ?: -1
}
fun sum(a: Int, b: Int) = a + b
fun vars(vararg v:Int){
for(vt in v) {
print(vt)
}
}
// 类型检测及自动类型转换
fun getStringLength(obj: Any): Int? {
if (obj is String) {
// 做过类型判断以后,obj会被系统自动转换为String类型
return obj.length
}
//在这里还有一种方法,与Java中instanceof不同,使用!is
// if (obj !is String){
// // XXX
// }
// 这里的obj仍然是Any类型的引用
return null
}
// 区间
fun main2(args: Array<String>) {
print("循环输出:")
for (i in 1..4) print(i) // 输出“1234”
println("\n----------------")
print("设置步长:")
for (i in 1..4 step 2) print(i) // 输出“13”
println("\n----------------")
print("使用 downTo:")
for (i in 4 downTo 1 step 2) print(i) // 输出“42”
println("\n----------------")
print("使用 until:")
// 使用 until 函数排除结束元素
for (i in 1 until 4) { // i in [1, 4) 排除了 4
print(i)
}
println("\n----------------")
}
}
二、数据类型
Kotlin 的基本数值类型包括 Byte、Short、Int、Long、Float、Double 等。不同于 Java 的是,字符不属于数值类型,是一个独立的数据类型。
Kotlin 中没有基础数据类型,只有封装的数字类型,你每定义的一个变量,其实 Kotlin 帮你封装了一个对象,这样可以保证不会出现空指针
// 字面常量
val oneMillion = 1_000_000
// 比较两个数字
val a: Int = 10000
println(a === a) // true,值相等,对象地址相等
//经过了装箱,创建了两个不同的对象
val boxedA: Int? = a
val anotherBoxedA: Int? = a
//虽然经过了装箱,但是值是相等的,都是10000
println(boxedA === anotherBoxedA) // false,值相等,对象地址不一样
println(boxedA == anotherBoxedA) // true,值相等
// 类型转换
val b: Byte = 1 // OK, 字面值是静态检测的
val i: Int = b.toInt() // OK
// 数组
val a = arrayOf(1, 2, 3)
val b = Array(3, { i -> (i * 2) })
//读取数组内容
println(a[0]) // 输出结果:1
println(b[1]) // 输出结果:2
// 字符串
val text = """
多行字符串
多行字符串
""".trimMargin()
// 字符串模板
val s = "runoob"
val str = "$s.length is ${s.length}" // 求值结果为 "runoob.length is 6"
val price = """
${'$'}9.99
"""
println(price) // 求值结果为 $9.99
三、条件控制、循环控制
// 1. IF 表达式
// 传统用法
var max = a
if (a < b) max = b
// 使用 else
var max: Int
if (a > b) {
max = a
} else {
max = b
}
// 作为表达式
val max = if (a > b) a else b
// 2. 使用区间
fun main(args: Array<String>) {
val x = 5
val y = 9
if (x in 1..8) {
println("x 在区间内")
}
}
// 3. When 表达式
when (x) {
in 1..10 -> print("x is in the range")
in validNumbers -> print("x is valid")
!in 10..20 -> print("x is outside the range")
else -> print("none of the above")
}
// 4. For 循环
fun main(args: Array<String>) {
val items = listOf("apple", "banana", "kiwi")
for (item in items) {
println(item)
}
for (index in items.indices) {
println("item at $index is ${items[index]}")
}
}
// 5. while 与 do...while 循环
fun main(args: Array<String>) {
println("----while 使用-----")
var x = 5
while (x > 0) {
println( x--)
}
println("----do...while 使用-----")
var y = 5
do {
println(y--)
} while(y>0)
}
四、类
Kotlin 类可以包含:构造函数和初始化代码块、函数、属性、内部类、对象声明。
Kotlin 中使用关键字 class 声明类,后面紧跟类名
Kotlin 类属性修饰符有:
- abstract 抽象类
- final 类不可继承,默认属性
- enum 枚举类
- open 类可继承,类默认是final的
- annotation 注解类
Kotlin 权限修饰符有:
- private 仅在同一个文件中可见
- protected 同一个文件中或子类可见
- public 所有调用的地方都可见
- internal 同一个模块中可见
////////// 定义一个空类
class Empty
// 定义User类
class User {
var name: String = "test"
fun test(name: String) {
var user = User()
user.name = name
}
}
class User constructor(name: String) {
init {
println("name is $name")
}
// 次构造函数
constructor (name: String, no: Int) : this(name) {
println("排名 $no")
}
var name: String = "test"
get() = field.toUpperCase()
set
var no: Int = 100
get() = field
set(value) {
if (value < 10) {
field = value
} else {
field = -1
}
}
}
////////// 抽象类
open class Base {
open fun f() {}
}
abstract class Derived : Base() {
override abstract fun f()
}
////////// 嵌套类
class Outer { // 外部类
private val bar: Int = 1
class Nested { // 嵌套类
fun foo() = 2
}
}
fun main(args: Array<String>) {
val demo = Outer.Nested().foo() // 调用格式:外部类.嵌套类.嵌套类方法/属性
println(demo) // == 2
}
////////// 内部类
class Outer {
private val bar: Int = 1
var v = "成员属性"
/**嵌套内部类**/
inner class Inner {
fun foo() = bar // 访问外部类成员
fun innerTest() {
var o = this@Outer //获取外部类的成员变量
println("内部类可以引用外部类的成员,例如:" + o.v)
}
}
}
fun main(args: Array<String>) {
val demo = Outer().Inner().foo()
println(demo) // 1
val demo2 = Outer().Inner().innerTest()
println(demo2) // 内部类可以引用外部类的成员,例如:成员属性
}
////////// 匿名内部类
class Test {
var v = "成员属性"
fun setInterFace(test: TestInterFace) {
test.test()
}
}
/**
* 定义接口
*/
interface TestInterFace {
fun test()
}
fun main(args: Array<String>) {
var test = Test()
/**
* 采用对象表达式来创建接口对象,即匿名内部类的实例。
*/
test.setInterFace(object : TestInterFace {
override fun test() {
println("对象表达式创建匿名内部类的实例")
}
})
}
五、接口
Kotlin 接口与 Java 8 类似,使用 interface 关键字定义接口,允许方法有默认实现:
interface MyInterface {
fun bar() // 未实现
fun foo() { //已实现
// 可选的方法体
println("foo")
}
}
六、继承
Kotlin 中所有类都继承该 Any 类,它是所有类的超类,对于没有超类型声明的类是默认超类
open class Person(var name : String, var age : Int) { // 基类
}
class Student(name : String, age : Int, var no : String, var score : Int) : Person(name, age) {
}
// 测试
fun main(args: Array<String>) {
val s = Student("Runoob", 18, "S12346", 89)
println("学生名: ${s.name}")
println("年龄: ${s.age}")
println("学生号: ${s.no}")
println("成绩: ${s.score}")
}
七、枚举类
enum class Color{
RED,BLACK,BLUE,GREEN,WHITE
}
enum class Color(val rgb: Int) {
RED(0xFF0000),
GREEN(0x00FF00),
BLUE(0x0000FF)
}
八、泛型
与 Java 一样,Kotlin 也提供泛型,为类型安全提供保证,消除类型强转的烦恼。
class Box<T>(t: T) {
var value = t
}
val box: Box<Int> = Box<Int>(1)
// 或者
val box = Box(1)