这一篇主要先回顾下Kotlin 基础语法,其实很多语法都是一通百通的,语法的可读性比java强,从左到右读的方式,还有几大特性几本都是所有编程语言都有的。
1.2 Kotlin 基础语法快速回顾
1.2.1 变量声明(val vs var)
核心概念:
val:不可变变量(类似 Java 的 final)var:可变变量
kotlin
// val - 不可变,推荐使用
val name = "张三"
// name = "李四" // 编译错误:val cannot be reassigned
// var - 可变,谨慎使用
var age = 25
age = 26 // 正确
// 类型推断
val explicitType: String = "明确类型"
val inferredType = "类型推断" // 编译器自动推断为 String
// 延迟初始化
lateinit var lazyInit: String
最佳实践:
- 优先使用 val,保证代码的不可变性
- 只有在确实需要修改时才使用 var
- 不可变性让代码更安全,更容易并发处理
1.2.2 函数定义与调用
基本语法:
kotlin
// 标准函数定义
fun greet(name: String): String {
return "你好,$name"
}
// 表达式体函数(单行函数)
fun greetShort(name: String): String = "你好,$name"
// 省略返回类型的表达式体函数(类型推断)
fun greetInfer(name: String) = "你好,$name"
// 默认参数值
fun createUser(
name: String,
age: Int = 18, // 默认值
email: String = ""
): User {
return User(name, age, email)
}
// 调用函数
val user1 = createUser("张三")
val user2 = createUser("李四", 25)
val user3 = createUser("王五", 30, "wang@example.com")
// 命名参数(提高可读性)
val user4 = createUser(
name = "赵六",
email = "zhao@example.com"
// age 使用默认值
)
可变参数(Varargs):
kotlin
// 可变参数
fun printAll(vararg messages: String) {
for (message in messages) {
println(message)
}
}
// 调用
printAll("消息1", "消息2", "消息3")
// 解构数组
val messages = arrayOf("A", "B", "C")
printAll(*messages) // 使用 * 操作符解构
1.2.3 类与继承
基础类定义:
kotlin
// 基础类
class Person {
var name: String = ""
var age: Int = 0
fun introduce() {
println("我是 $name,今年 $age 岁")
}
}
// 使用
val person = Person()
person.name = "张三"
person.age = 25
person.introduce()
主构造函数:
kotlin
// 主构造函数
class User(val name: String, var age: Int) {
// init 块在构造时执行
init {
println("创建用户:$name")
}
fun greet() {
println("你好,我是 $name,$age 岁")
}
}
// 使用
val user = User("李四", 30)
user.greet()
次构造函数:
kotlin
class User2(val name: String) {
var age: Int = 0
var email: String = ""
// 主构造函数
constructor(name: String, age: Int) : this(name) {
this.age = age
}
// 次构造函数
constructor(name: String, age: Int, email: String) : this(name, age) {
this.email = email
}
}
继承:
kotlin
// 父类(使用 open 关键字允许继承)
open class Animal(val name: String) {
open fun makeSound() {
println("$name 发出声音")
}
}
// 子类
class Dog(name: String) : Animal(name) {
override fun makeSound() {
println("$name:汪汪汪")
}
}
class Cat(name: String) : Animal(name) {
override fun makeSound() {
println("$name:喵喵喵")
}
}
// 使用
val dog = Dog("旺财")
dog.makeSound() // 输出:旺财:汪汪汪
val cat = Cat("咪咪")
cat.makeSound() // 输出:咪咪:喵喵喵
继承的关键点:
- 父类需要使用
open关键字才能被继承 - 重写的方法需要使用
override关键字 - 子类构造函数必须调用父类构造函数
1.2.4 接口与抽象类
接口:
kotlin
// 接口定义
interface Clickable {
fun click()
fun showOff() = println("我是可点击的!") // 默认实现
}
// 实现接口
class Button : Clickable {
override fun click() {
println("按钮被点击")
}
// showOff() 使用默认实现
}
// 多个接口实现
interface Focusable {
fun setFocus(b: Boolean) {
println("焦点设置: $b")
}
}
class TextView : Clickable, Focusable {
override fun click() {
println("文本框被点击")
}
// setFocus() 使用默认实现
}
抽象类:
kotlin
// 抽象类
abstract class Shape {
// 抽象方法
abstract fun area(): Double
// 具体方法
fun describe() {
println("这是一个形状,面积是 ${area()}")
}
}
// 继承抽象类
class Circle(private val radius: Double) : Shape() {
override fun area(): Double {
return Math.PI * radius * radius
}
}
class Rectangle(private val width: Double, private val height: Double) : Shape() {
override fun area(): Double {
return width * height
}
}
// 使用
val circle = Circle(5.0)
circle.describe() // 输出:这是一个形状,面积是 78.53981633974483
val rectangle = Rectangle(4.0, 5.0)
rectangle.describe() // 输出:这是一个形状,面积是 20.0
接口 vs 抽象类选择指南:
- 接口:定义行为契约,支持多重实现
- 抽象类:定义模板和共享状态,单继承