网站首页 > 精选教程 正文
1. 类与对象设计
1.1 类声明简化
基本类声明对比:
// Java
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// getters/setters...
}
// Kotlin
class Person(val name: String, var age: Int)
关键差异:
- 主构造器直接写在类头
- val/var参数自动生成属性和字段
- 默认public可见性
- 默认final类(不可继承)
1.2 数据类(Data Class)
POJO转换示例:
// Java
public class User {
private String username;
private String email;
// 构造器、getters、setters、equals、hashCode、toString...
// 通常需要50+行代码
}
// Kotlin
data class User(val username: String, val email: String)
// 自动生成:equals()/hashCode()/toString()/copy()/componentN()
数据类特性:
- 自动生成标准方法
- 解构声明支持:val (name, email) = user // 自动分解为组件
- copy方法用于不可变对象的修改:val updatedUser = user.copy(email = "new@email.com")
1.3 单例对象(Object Declaration)
单例模式对比:
// Java
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return INSTANCE;
}
}
// Kotlin
object Singleton {
fun doSomething() { ... }
}
// 使用:Singleton.doSomething()
伴生对象(Companion Object):
class MyClass {
companion object {
const val CONSTANT = "value"
fun factory() = MyClass()
}
}
// 使用:MyClass.CONSTANT 或 MyClass.factory()
2. 继承与接口
2.1 继承体系
基本继承语法:
open class Animal(val name: String) { // 必须标记open才能被继承
open fun makeSound() { ... } // 必须标记open才能被重写
}
class Dog(name: String) : Animal(name) {
override fun makeSound() {
super.makeSound()
println("Bark!")
}
}
与Java的关键差异:
- 默认final类(必须显式声明open才能继承)
- 使用冒号(:)代替extends/implements
- 主构造器调用必须立即发生
2.2 接口增强
带默认方法的接口:
interface Clickable {
fun click() // 抽象方法
fun showOff() = println("I'm clickable!") // 默认实现
}
interface Focusable {
fun showOff() = println("I'm focusable!")
}
class Button : Clickable, Focusable {
override fun click() = println("Clicked")
// 必须解决接口冲突
override fun showOff() {
super<Clickable>.showOff()
super<Focusable>.showOff()
}
}
接口属性:
interface User {
val nickname: String // 抽象属性
val email: String
get() = "$nickname@example.com" // 提供getter实现
}
3. 属性与字段
3.1 属性声明
完整属性语法:
class Person(name: String) {
var name: String = name
get() = field.capitalize() // 后备字段(field)
set(value) {
if (value.isNotBlank()) field = value
}
}
与Java Bean的对应关系:
- var自动生成getter/setter
- val只生成getter
- 自定义访问器提供额外逻辑
3.2 延迟初始化
lateinit var:
class MyTest {
lateinit var service: Service // 不能是原始类型
@Before fun setUp() {
service = Service() // 延迟初始化
}
@Test fun test() {
if (::service.isInitialized) { // 反射检查
service.doSomething()
}
}
}
惰性初始化(by lazy):
val heavyObject: HeavyObject by lazy {
println("Initializing...")
HeavyObject() // 首次访问时初始化
}
4. 扩展函数与属性
4.1 扩展函数
集合操作示例:
fun <T> List<T>.penultimate(): T {
if (size < 2)
throw NoSuchElementException()
return this[size - 2]
}
// 使用
val list = listOf(1, 2, 3)
println(list.penultimate()) // 输出2
Java调用扩展函数:
// Java中调用Kotlin扩展函数
ListUtilKt.penultimate(list);
4.2 扩展属性
实现示例:
val String.lastChar: Char
get() = get(length - 1)
var StringBuilder.lastChar: Char
get() = get(length - 1)
set(value) = setCharAt(length - 1, value)
注意事项:
- 不能有后备字段
- 实际上是语法糖(编译为静态方法)
- 作用域控制很重要(避免污染全局命名空间)
5. 集合API
5.1 集合体系结构
Kotlin集合层次:
- IterableMutableIterable
- CollectionMutableCollection
- List/Set/MapMutableList/MutableSet/MutableMap
创建集合:
val readOnlyList = listOf(1, 2, 3)
val mutableList = mutableListOf(1, 2, 3)
val map = mapOf(1 to "one", 2 to "two")
5.2 函数式操作
常用操作符:
val numbers = listOf(1, 2, 3, 4)
// 转换
numbers.map { it * 2 } // [2, 4, 6, 8]
numbers.flatMap { listOf(it, it) } // [1,1,2,2,3,3,4,4]
// 过滤
numbers.filter { it % 2 == 0 } // [2, 4]
numbers.filterNot { it % 2 == 0 } // [1, 3]
// 聚合
numbers.reduce { acc, i -> acc + i } // 10
numbers.fold(10) { acc, i -> acc + i } // 20
// 查找
numbers.find { it > 2 } // 3
numbers.firstOrNull { it > 5 } // null
序列(Sequence)优化:
list.asSequence()
.filter { it % 2 == 0 }
.map { it * 2 }
.toList() // 延迟计算,避免中间集合创建
6. 泛型系统
6.1 声明处型变(Declaration-site Variance)
in/out修饰符:
interface Producer<out T> { // 协变
fun produce(): T
}
interface Consumer<in T> { // 逆变
fun consume(item: T)
}
// 使用
val producer: Producer<Animal> = Producer<Dog>()
val consumer: Consumer<Dog> = Consumer<Animal>()
6.2 类型投影(Use-site Variance)
Java通配符对应:
// Kotlin
fun copy(from: Array<out Any>, to: Array<Any>) { ... }
// 相当于Java的
void copy(Array<? extends Object> from, Array<Object> to)
星投影(Star Projection):
fun printSize(list: List<*>) {
println(list.size) // 可以调用不依赖类型参数的方法
}
7. 函数式编程
7.1 Lambda表达式
语法简化:
// 完整形式
val sum = { x: Int, y: Int -> x + y }
// 类型推断
val sum: (Int, Int) -> Int = { x, y -> x + y }
// 单参数隐式it
list.filter { it % 2 == 0 }
SAM转换:
// Java接口
interface Runnable {
void run();
}
// Kotlin使用
val runnable = Runnable { println("Running") }
7.2 高阶函数
函数作为参数:
fun calculate(x: Int, y: Int, operation: (Int, Int) -> Int): Int {
return operation(x, y)
}
// 调用
calculate(2, 3, { a, b -> a * b }) // 6
calculate(2, 3) { a, b -> a + b } // 5 (尾随lambda)
返回函数:
fun operationSelector(op: String): (Int, Int) -> Int {
return when (op) {
"+" -> { a, b -> a + b }
"*" -> { a, b -> a * b }
else -> throw IllegalArgumentException()
}
}
// 使用
val add = operationSelector("+")
println(add(2, 3)) // 5
7.3 内联函数
性能优化:
inline fun <T> lock(lock: Lock, body: () -> T): T {
lock.lock()
try {
return body()
} finally {
lock.unlock()
}
}
// 调用处会内联展开,避免lambda对象创建
限制:
- 内联函数不能递归
- 公有API的内联函数不能使用非公有API
- 参数不能存储在字段中
8. 作用域函数
8.1 五种作用域函数对比
函数 | 上下文对象引用 | 返回值 | 典型使用场景 |
let | it | lambda结果 | 非空对象处理 |
run | this | lambda结果 | 对象配置计算 |
with | this | lambda结果 | 对象分组调用 |
apply | this | 对象本身 | 对象初始化 |
also | it | 对象本身 | 附加效果 |
8.2 使用示例
对象初始化链:
val dialog = AlertDialog.Builder(context).apply {
setTitle("Warning")
setMessage("Are you sure?")
setPositiveButton("OK") { _, _ -> }
setNegativeButton("Cancel", null)
}.create()
数据处理管道:
val result = input?.let {
it.trim()
}?.takeIf {
it.isNotEmpty()
}?.run {
parse(this)
} ?: defaultValue
9. 委托模式
9.1 类委托
实现模式:
interface Database {
fun save(data: String)
}
class RealDatabase : Database {
override fun save(data: String) { /*...*/ }
}
class ProxyDatabase(db: Database) : Database by db // 自动转发所有方法
9.2 属性委托
内置委托:
// 惰性初始化
val lazyValue: String by lazy {
println("computed!")
"Hello"
}
// 观察属性变化
var observed: String by Delegates.observable("初始值") {
prop, old, new ->
println("$old -> $new")
}
自定义委托:
class StringDelegate(private var value: String) {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
println("读取 ${property.name}")
return value
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
println("设置 ${property.name} = $value")
this.value = value
}
}
// 使用
var str by StringDelegate("默认值")
str = "新值" // 日志:设置 str = 新值
println(str) // 日志:读取 str → 输出"新值"
10. 注解与反射
10.1 常用注解
互操作注解:
- @JvmStatic:生成静态方法
- @JvmOverloads:生成重载方法
- @JvmField:暴露为字段(而非属性)
空安全注解:
// Java
public @Nullable String getName() { ... }
public @NotNull String getRequiredName() { ... }
// Kotlin调用
val name = javaObj.name // String?
val required = javaObj.requiredName // String
10.2 反射API
基本用法:
class Person(val name: String, var age: Int)
fun reflect() {
val person = Person("Alice", 25)
val kClass = person::class
// 获取属性
val ageProp = kClass.memberProperties.find { it.name == "age" }
if (ageProp is KMutableProperty<*>) {
ageProp.setter.call(person, 26)
}
println(person.age) // 26
}
与Java反射互操作:
val javaClass = person.javaClass
val kotlinClass = javaClass.kotlin // 转换回Kotlin反射API
11. Java互操作深入
11.1 类型映射
特殊类型处理:
- void → Unit
- Java原始类型 → Kotlin非空类型(int → Int)
- Java集合类型 → Kotlin平台类型(List → (Mutable)List<String!>!)
数组处理:
// Java方法:public String[] getNames()
val names = javaObj.names // Array<String>!(平台类型)
val first = names[0] // String!(平台类型)
// 原始类型数组
val intArray = javaObj.intArray // IntArray!(对应Java的int[])
11.2 异常处理差异
受检异常处理:
// Java方法:public void write() throws IOException
fun writeSafely() {
try {
javaObj.write()
} catch (e: IOException) { // 不是必须捕获
// 处理异常
}
}
结语
中篇深入探讨了Kotlin在面向对象和函数式编程方面的特性,展示了如何用更简洁的语法实现更强大的抽象。这些特性包括:
- 数据类和单例对象的声明简化
- 扩展函数对现有类的无侵入式增强
- 丰富的集合操作API
- 灵活的函数式编程支持
- 强大的委托模式
下篇将聚焦于协程、DSL构建、性能优化和实际迁移策略,帮助开发者完成从Java到Kotlin的完整过渡。
猜你喜欢
- 2025-05-11 Kotlin 2.0强势发布:开发体验吊打Java,IDEA 新时代到来了
- 2025-05-11 通过对比语法差异,让会JAVA的你快速学会Kotlin的开源宝藏项目
- 2025-05-11 对于Android程序开发用java好还是kotlin好
- 2025-05-11 Java和Kotlin共存
- 2025-05-11 kotlin和java开发哪个好,优缺点对比
你 发表评论:
欢迎- 06-30【AI绘永昌】风景篇(二)(永昌图文)
- 06-30AI风景建筑图集(ai景观平面图)
- 06-30AI绘制精美绚丽的景色(ai绘制图案)
- 06-30AI风景,不存在的地方又增加了(ai风景插画作品)
- 06-301 分钟解锁!运用 DS + 即梦 + 豆包,轻松打造个性化风景音乐短视频
- 06-30美景欣赏 #AI绘画#(美景图画)
- 06-30AI动漫风景图集1 ~(ai动漫图片)
- 06-30原图壁纸,ai绘画风景(原图壁纸下载)
- 最近发表
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)