markdown复制## 1. Kotlin类基础:从声明到实例化
Kotlin的类声明比Java简洁得多,一个完整的类定义只需要一行代码。比如定义一个Person类:
```kotlin
class Person(val name: String, var age: Int)
这行代码同时完成了:
- 类声明
- 两个属性的定义(name为只读,age可修改)
- 构造函数定义
实例化对象时,Kotlin不需要new关键字:
kotlin复制val person = Person("张三", 25)
注意:Kotlin中默认类都是final的,无法被继承。如果需要允许继承,必须显式添加
open修饰符。
类的函数定义也很直观:
kotlin复制fun greet() {
println("你好,我是$name")
}
1.1 构造函数的多种写法
Kotlin支持主构造函数和次构造函数。主构造函数直接写在类头中,次构造函数使用constructor关键字:
kotlin复制class User {
constructor(name: String) {
// 初始化代码
}
constructor(name: String, age: Int) {
// 另一个构造函数
}
}
更常见的做法是结合默认参数:
kotlin复制class User(val name: String, val age: Int = 18)
这样既可以User("李四")也可以User("王五", 20)。
2. 类成员详解
2.1 属性与字段
Kotlin的属性会自动生成getter/setter。如果需要自定义访问逻辑:
kotlin复制var score: Int = 0
get() = if (field < 0) 0 else field
set(value) {
field = if (value > 100) 100 else value
}
技巧:使用
field标识符访问幕后字段,避免递归调用。
2.2 延迟初始化
对于非空属性但不想在构造函数初始化的情况:
kotlin复制lateinit var config: Config
使用时需先初始化,否则会抛出UninitializedPropertyAccessException。
2.3 伴生对象
相当于Java的静态成员,使用companion object:
kotlin复制class MyClass {
companion object {
const val MAX_COUNT = 100
fun create(): MyClass = MyClass()
}
}
调用方式:MyClass.MAX_COUNT
3. 高级类特性
3.1 数据类
自动生成equals()、hashCode()、toString()等:
kotlin复制data class Book(val title: String, val author: String)
数据类支持解构声明:
kotlin复制val (title, author) = book
3.2 密封类
限制类继承结构的枚举增强版:
kotlin复制sealed class Result {
data class Success(val data: String) : Result()
data class Error(val message: String) : Result()
}
配合when表达式使用时,编译器会检查是否覆盖所有情况。
3.3 内联类
Kotlin 1.3引入的值类型包装:
kotlin复制inline class Password(val value: String)
运行时会被优化为原始类型,避免对象创建开销。
4. 类继承与接口
4.1 继承语法
Kotlin使用:代替Java的extends:
kotlin复制open class Animal(val name: String)
class Dog(name: String) : Animal(name)
4.2 接口实现
接口可以包含默认实现:
kotlin复制interface Flyable {
fun fly() {
println("飞行中...")
}
}
4.3 抽象类
与Java类似,但可以包含非抽象成员:
kotlin复制abstract class Shape {
abstract fun draw()
fun rotate() {
println("旋转图形")
}
}
5. 对象表达式与声明
5.1 对象表达式
创建匿名类实例:
kotlin复制val listener = object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
// 处理点击
}
}
5.2 对象声明
单例模式实现:
kotlin复制object Database {
fun connect() {
// 连接数据库
}
}
使用方式:Database.connect()
6. 类型检查与转换
6.1 智能类型转换
Kotlin编译器会自动处理类型转换:
kotlin复制if (obj is String) {
println(obj.length) // 自动转为String类型
}
6.2 安全转换操作符
避免ClassCastException:
kotlin复制val str: String? = obj as? String
7. 泛型类
7.1 基本用法
kotlin复制class Box<T>(t: T) {
var value = t
}
7.2 型变注解
out协变和in逆变:
kotlin复制interface Source<out T> {
fun next(): T
}
interface Sink<in T> {
fun put(item: T)
}
8. 扩展函数与属性
8.1 扩展函数
为现有类添加方法:
kotlin复制fun String.addExclamation() = "$this!"
使用:"Hello".addExclamation()
8.2 扩展属性
kotlin复制val String.lastChar: Char
get() = this[length - 1]
9. 委托机制
9.1 类委托
kotlin复制interface Base {
fun print()
}
class BaseImpl(val x: Int) : Base {
override fun print() { print(x) }
}
class Derived(b: Base) : Base by b
9.2 属性委托
标准委托包括:
- lazy
- observable
- vetoable
- map
自定义委托:
kotlin复制class Example {
var p: String by Delegate()
}
10. 实际应用技巧
10.1 Android开发中的类使用
在Android中常见用法:
kotlin复制class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
10.2 与Java互操作
Kotlin类会被编译为JVM字节码,Java可以正常调用。需要注意:
- Kotlin属性会编译为getter/setter
- 伴生对象成员会生成静态成员
- 顶级函数会生成静态方法
10.3 性能优化建议
- 优先使用数据类而非普通类
- 考虑使用内联类减少对象创建
- 合理使用
const val定义编译期常量 - 对于工具类,使用对象声明而非类
11. 常见问题排查
-
继承问题:忘记添加
open修饰符导致无法继承- 解决方案:在父类声明前添加
open
- 解决方案:在父类声明前添加
-
空安全异常:对非空属性未初始化
- 解决方案:使用
lateinit或可空类型
- 解决方案:使用
-
类型转换失败:使用
as进行不安全转换- 解决方案:改用
as?安全转换操作符
- 解决方案:改用
-
伴生对象访问问题:从Java代码调用伴生对象成员
- 解决方案:使用
@JvmStatic注解
- 解决方案:使用
-
数据类equals不一致:包含可变属性
- 解决方案:避免在数据类中使用var属性
12. 最佳实践建议
-
类设计原则:
- 保持类职责单一
- 优先使用不可变属性
- 合理使用数据类
-
命名规范:
- 类名使用大驼峰
- 属性/方法使用小驼峰
- 常量全大写
-
文档注释:
kotlin复制/** * 用户实体类 * @property name 用户名 * @constructor 创建用户实例 */ class User(val name: String) -
测试建议:
- 为重要类编写单元测试
- 使用MockK进行mock测试
- 验证数据类的equals/hashCode行为
13. Kotlin 1.7+新特性
- 上下文接收器:
kotlin复制context(View)
fun update() {
// 可以直接访问View的成员
}
- 允许内联类作为类型参数:
kotlin复制inline class Name(val value: String)
fun printName(name: Name) {
println(name.value)
}
- 稳定版的值类:
kotlin复制@JvmInline
value class Password(val value: String)
14. 实际项目案例
14.1 用户管理系统
kotlin复制data class User(
val id: Long,
val username: String,
val email: String,
val createdAt: Instant
) {
fun isActive(): Boolean {
// 业务逻辑
}
}
object UserRepository {
private val users = mutableListOf<User>()
fun addUser(user: User) {
users.add(user)
}
}
14.2 Android ViewModel
kotlin复制class MainViewModel : ViewModel() {
private val _data = MutableLiveData<String>()
val data: LiveData<String> = _data
fun loadData() {
viewModelScope.launch {
_data.value = repository.fetchData()
}
}
}
15. 调试与优化
-
使用
toString()调试:- 数据类自动生成有意义的toString
- 普通类建议重写
-
日志记录:
kotlin复制class Service {
companion object {
private val logger = Logger.getLogger(Service::class.java.simpleName)
}
fun process() {
logger.info("开始处理")
}
}
- 性能分析:
- 使用Android Profiler
- 检查对象分配情况
- 优化高频创建的类
16. 跨平台应用
Kotlin Multiplatform中的类使用:
kotlin复制expect class Platform() {
val platform: String
}
class Greeting {
fun greet(): String {
return "Hello, ${Platform().platform}"
}
}
17. 协程与类
在类中使用协程:
kotlin复制class DataLoader {
suspend fun loadData(): String {
return withContext(Dispatchers.IO) {
// 网络请求
}
}
}
18. 反射与注解
18.1 类反射
kotlin复制val klass = MyClass::class
klass.members.forEach { println(it.name) }
18.2 自定义注解
kotlin复制@Target(AnnotationTarget.CLASS)
annotation class Api(val path: String)
@Api("/users")
class UserController
19. 设计模式实现
19.1 工厂模式
kotlin复制interface Animal {
fun speak()
}
class Dog : Animal {
override fun speak() = println("汪汪")
}
class AnimalFactory {
fun create(type: String): Animal {
return when(type) {
"dog" -> Dog()
else -> throw IllegalArgumentException()
}
}
}
19.2 观察者模式
kotlin复制class Subject {
private val observers = mutableListOf<Observer>()
fun addObserver(observer: Observer) {
observers.add(observer)
}
fun notifyObservers() {
observers.forEach { it.update() }
}
}
interface Observer {
fun update()
}
20. 测试策略
20.1 单元测试
kotlin复制class CalculatorTest {
@Test
fun testAdd() {
val calc = Calculator()
assertEquals(5, calc.add(2, 3))
}
}
20.2 Mock测试
kotlin复制@Test
fun testUserService() {
val mockRepo = mockk<UserRepository>()
every { mockRepo.getUser(any()) } returns User(1, "test")
val service = UserService(mockRepo)
val user = service.getUser(1)
assertEquals("test", user.username)
}
