在 Android Kotlin 开发中,类、对象和接口 是面向对象编程的核心基础。常见的 Activity、Fragment、ViewModel、Adapter、Repository、Service 等,本质上都离不开类、对象、继承和接口。
简单理解:
text
类是对象的模板,对象是类的具体实例。
接口定义规范,具体类负责实现。
一、类与对象
1. 什么是类?
类可以理解为一种模板,用来描述一类事物的属性和行为。
在 Kotlin 中使用 class 关键字定义类:
kotlin
class User {
var name: String = "张三"
var age: Int = 18
fun login() {
println("$name 正在登录")
}
}
| 内容 | 说明 |
|---|---|
class User |
定义一个 User 类 |
name |
用户姓名属性 |
age |
用户年龄属性 |
login() |
用户登录函数 |
2. 什么是对象?
对象是通过类创建出来的具体实例。
kotlin
val user = User()
完整示例:
kotlin
class User {
var name: String = "张三"
var age: Int = 18
fun login() {
println("$name 正在登录")
}
}
fun main() {
val user = User()
println(user.name)
println(user.age)
user.login()
}
输出结果:
text
张三
18
张三 正在登录
通过对象访问属性和方法:
kotlin
user.name
user.age
user.login()
3. 类和对象的关系
| 概念 | 说明 |
|---|---|
| 类 | 模板、图纸、设计方案 |
| 对象 | 根据类创建出来的具体实例 |
示例:
kotlin
class User {
var name: String = ""
var age: Int = 0
}
fun main() {
val user1 = User()
user1.name = "张三"
user1.age = 18
val user2 = User()
user2.name = "李四"
user2.age = 20
println(user1.name)
println(user2.name)
}
输出结果:
text
张三
李四
user1 和 user2 都来自 User 类,但它们是两个不同的对象。
4. 类中的属性
类中的变量通常称为属性。
kotlin
class User {
var name: String = "张三"
var age: Int = 18
}
访问属性:
kotlin
val user = User()
println(user.name)
println(user.age)
修改属性:
kotlin
user.name = "李四"
user.age = 20
完整示例:
kotlin
class User {
var name: String = "张三"
var age: Int = 18
}
fun main() {
val user = User()
println("修改前:${user.name}, ${user.age}")
user.name = "李四"
user.age = 20
println("修改后:${user.name}, ${user.age}")
}
5. 类中的函数
类中的函数通常称为成员函数,也可以理解为对象的行为。
kotlin
class User {
var name: String = "张三"
fun login() {
println("$name 登录成功")
}
fun logout() {
println("$name 退出登录")
}
}
fun main() {
val user = User()
user.login()
user.logout()
}
输出结果:
text
张三 登录成功
张三 退出登录
6. 主构造函数
Kotlin 中可以直接在类名后面定义构造函数。
kotlin
class User(val name: String, val age: Int)
使用:
kotlin
fun main() {
val user = User("张三", 18)
println("姓名:${user.name}")
println("年龄:${user.age}")
}
输出结果:
text
姓名:张三
年龄:18
这种写法非常简洁,是 Kotlin 中很常用的写法。
7. 主构造函数中的 val 和 var
构造函数参数前面可以加 val 或 var。
kotlin
class User(val name: String, var age: Int)
| 写法 | 说明 |
|---|---|
val name: String |
只读属性,创建后不能重新赋值 |
var age: Int |
可变属性,创建后可以修改 |
示例:
kotlin
class User(val name: String, var age: Int)
fun main() {
val user = User("张三", 18)
println(user.name)
println(user.age)
user.age = 20
println(user.age)
// user.name = "李四" // 错误,name 是 val
}
8. 构造函数参数不加 val 或 var
如果构造函数参数前面不加 val 或 var,它只是普通参数,不会成为类的属性。
kotlin
class User(name: String, age: Int) {
fun printInfo() {
// name 和 age 不会自动成为可访问属性
}
}
常用写法还是:
kotlin
class User(val name: String, val age: Int)
或者:
kotlin
class User(var name: String, var age: Int)
9. init 初始化代码块
如果需要在创建对象时执行一些初始化逻辑,可以使用 init 代码块。
kotlin
class User(val name: String, val age: Int) {
init {
println("创建了一个 User 对象")
println("姓名:$name,年龄:$age")
}
}
fun main() {
val user = User("张三", 18)
}
输出结果:
text
创建了一个 User 对象
姓名:张三,年龄:18
10. 次构造函数
Kotlin 中也支持次构造函数,使用 constructor 关键字。
kotlin
class User {
var name: String = ""
var age: Int = 0
constructor(name: String, age: Int) {
this.name = name
this.age = age
}
}
使用:
kotlin
val user = User("张三", 18)
不过在 Kotlin 中,更多时候推荐使用主构造函数:
kotlin
class User(var name: String, var age: Int)
11. this 关键字
this 表示当前对象。
当属性名和参数名相同时,可以用 this 区分。
kotlin
class User {
var name: String = ""
fun setUserName(name: String) {
this.name = name
}
}
这里:
kotlin
this.name
表示类中的属性。
而:
kotlin
name
表示函数参数。
12. 访问修饰符
Kotlin 中常用访问修饰符有:
| 修饰符 | 说明 |
|---|---|
public |
默认,任何地方都可以访问 |
private |
只能在当前类中访问 |
protected |
当前类和子类可以访问 |
internal |
当前模块内可以访问 |
public
默认就是 public,可以省略。
kotlin
class User {
var name: String = "张三"
}
private
private 表示只能在当前类中访问。
kotlin
class User {
private var password: String = "123456"
fun printPassword() {
println(password)
}
}
外部不能直接访问:
kotlin
val user = User()
// println(user.password) // 错误
Android 中常见写法:
kotlin
class MainActivity : AppCompatActivity() {
private lateinit var loginButton: Button
private fun initView() {
loginButton = findViewById(R.id.loginButton)
}
}
13. getter 和 setter
Kotlin 中属性默认会自动生成 getter 和 setter。
kotlin
class User {
var name: String = "张三"
}
访问:
kotlin
println(user.name)
修改:
kotlin
user.name = "李四"
也可以自定义 getter 和 setter:
kotlin
class User {
var name: String = "张三"
get() = field
set(value) {
field = value
}
}
其中 field 表示当前属性的真实存储字段。
示例:设置年龄时做限制。
kotlin
class User {
var age: Int = 0
set(value) {
field = if (value < 0) 0 else value
}
}
fun main() {
val user = User()
user.age = -10
println(user.age)
}
输出结果:
text
0
14. lateinit 延迟初始化
Android 中经常会用到 lateinit。
如果一个变量不能马上初始化,但后面一定会初始化,可以使用 lateinit。
kotlin
private lateinit var loginButton: Button
示例:
kotlin
class MainActivity : AppCompatActivity() {
private lateinit var loginButton: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
loginButton = findViewById(R.id.loginButton)
}
}
lateinit 常用于:
text
View
Adapter
ViewModel
RecyclerView
Toolbar
注意:
kotlin
lateinit var name: String
只能用于 var,不能用于 val。
不能用于基本类型,比如:
kotlin
lateinit var age: Int // 错误
如果在初始化之前使用,会报错:
text
UninitializedPropertyAccessException
15. data class 数据类
在 Android 中,经常需要定义实体类,比如用户、文章、商品等。
Kotlin 提供了 data class,专门用来保存数据。
kotlin
data class User(
val name: String,
val age: Int
)
使用:
kotlin
val user = User("张三", 18)
println(user.name)
println(user.age)
println(user)
输出结果:
text
张三
18
User(name=张三, age=18)
data class 会自动生成:
| 方法 | 作用 |
|---|---|
toString() |
打印对象内容 |
equals() |
比较对象内容 |
hashCode() |
生成哈希值 |
copy() |
复制对象 |
componentN() |
解构声明 |
copy 示例
kotlin
val user1 = User("张三", 18)
val user2 = user1.copy(age = 20)
println(user1)
println(user2)
输出结果:
text
User(name=张三, age=18)
User(name=张三, age=20)
Android 中常见数据类:
kotlin
data class Article(
val title: String,
val content: String,
val author: String
)
16. object 单例对象
Kotlin 中可以使用 object 创建单例对象。
单例对象表示整个程序中只有一个实例。
kotlin
object UserManager {
var token: String = ""
fun login() {
println("用户登录")
}
fun logout() {
println("用户退出")
}
}
使用:
kotlin
UserManager.token = "abc123"
UserManager.login()
不需要创建对象:
kotlin
// val manager = UserManager() // 错误
Android 中常用于:
text
用户管理
登录状态管理
全局配置
工具类
常量管理
示例:
kotlin
object AppConfig {
const val BASE_URL = "https://api.example.com"
const val TIME_OUT = 30
}
fun main() {
println(AppConfig.BASE_URL)
}
17. companion object 伴生对象
companion object 类似 Java 中的 static。
Kotlin 没有 static 关键字,通常使用 companion object 实现类似静态成员的效果。
kotlin
class User {
companion object {
const val TYPE_ADMIN = 1
const val TYPE_NORMAL = 2
fun createDefaultUser(): User {
return User()
}
}
}
使用:
kotlin
println(User.TYPE_ADMIN)
val user = User.createDefaultUser()
Android 中常见写法:
kotlin
class DetailActivity : AppCompatActivity() {
companion object {
const val EXTRA_USER_ID = "extra_user_id"
}
}
使用:
kotlin
intent.putExtra(DetailActivity.EXTRA_USER_ID, "1001")
18. 继承
Kotlin 中类默认不能被继承。
如果一个类允许被继承,需要使用 open 修饰。
kotlin
open class Animal {
fun eat() {
println("动物吃东西")
}
}
class Dog : Animal()
fun main() {
val dog = Dog()
dog.eat()
}
输出结果:
text
动物吃东西
19. 重写父类方法
如果父类的方法允许被重写,也需要加 open。
kotlin
open class Animal {
open fun eat() {
println("动物吃东西")
}
}
class Dog : Animal() {
override fun eat() {
println("狗吃骨头")
}
}
fun main() {
val dog = Dog()
dog.eat()
}
输出结果:
text
狗吃骨头
20. Android 中的继承
Android 中最常见的继承就是 Activity。
kotlin
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
其中:
| 代码 | 说明 |
|---|---|
: AppCompatActivity() |
继承父类 |
override fun onCreate() |
重写父类生命周期方法 |
super.onCreate() |
调用父类方法 |
21. 抽象类
抽象类使用 abstract 修饰。
抽象类不能直接创建对象,只能被子类继承。
kotlin
abstract class BaseRepository {
abstract fun loadData()
fun clearCache() {
println("清理缓存")
}
}
class UserRepository : BaseRepository() {
override fun loadData() {
println("加载用户数据")
}
}
fun main() {
val repository = UserRepository()
repository.loadData()
repository.clearCache()
}
22. 匿名对象
Kotlin 可以使用 object : 接口名 创建匿名对象。
Android 中非常常见。
kotlin
button.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
println("按钮被点击")
}
})
不过 Kotlin 中通常可以简写成 Lambda:
kotlin
button.setOnClickListener {
println("按钮被点击")
}
23. inner class 内部类
默认情况下,Kotlin 的嵌套类不能直接访问外部类成员。
如果想让内部类访问外部类成员,需要使用 inner。
kotlin
class Outer {
val name = "外部类"
inner class Inner {
fun printName() {
println(name)
}
}
}
fun main() {
val outer = Outer()
val inner = outer.Inner()
inner.printName()
}
输出结果:
text
外部类
24. sealed class 密封类
sealed class 常用于表示有限的状态。
比如页面状态只有几种:
kotlin
sealed class UiState {
object Loading : UiState()
data class Success(val data: String) : UiState()
data class Error(val message: String) : UiState()
}
使用 when 处理:
kotlin
fun handleState(state: UiState) {
when (state) {
is UiState.Loading -> {
println("加载中")
}
is UiState.Success -> {
println("加载成功:${state.data}")
}
is UiState.Error -> {
println("加载失败:${state.message}")
}
}
}
Android 中常用于:
text
页面状态
网络请求状态
登录状态
业务结果封装
25. enum class 枚举类
枚举类用于表示固定的一组值。
kotlin
enum class LoginState {
SUCCESS,
FAILED,
LOADING
}
使用:
kotlin
val state = LoginState.SUCCESS
when (state) {
LoginState.SUCCESS -> println("登录成功")
LoginState.FAILED -> println("登录失败")
LoginState.LOADING -> println("登录中")
}
Android 中可以用来表示:
text
页面类型
登录状态
网络状态
按钮状态
订单状态
26. 类与对象在 Android 中的常见使用
Activity 类
kotlin
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
MainActivity 是一个类,系统会创建它的对象并执行生命周期方法。
数据实体类
kotlin
data class User(
val id: Int,
val name: String,
val age: Int
)
使用:
kotlin
val user = User(1, "张三", 18)
println(user.name)
工具类对象
kotlin
object ToastUtils {
fun show(context: Context, message: String) {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
}
}
使用:
kotlin
ToastUtils.show(this, "保存成功")
ViewModel 类
kotlin
class UserViewModel : ViewModel() {
fun loadUserInfo() {
println("加载用户信息")
}
}
Repository 类
kotlin
class UserRepository {
fun getUserList(): List<User> {
return listOf(
User(1, "张三", 18),
User(2, "李四", 20)
)
}
}
27. 完整示例:User 类的定义和使用
kotlin
data class User(
val id: Int,
var name: String,
var age: Int
) {
fun printInfo() {
println("用户ID:$id,姓名:$name,年龄:$age")
}
fun updateAge(newAge: Int) {
if (newAge < 0) {
println("年龄不能小于 0")
return
}
age = newAge
}
}
fun main() {
val user = User(1, "张三", 18)
user.printInfo()
user.name = "李四"
user.updateAge(20)
user.printInfo()
}
输出结果:
text
用户ID:1,姓名:张三,年龄:18
用户ID:1,姓名:李四,年龄:20
28. 完整 Android 示例:登录用户管理
kotlin
data class User(
val id: Int,
val username: String,
val token: String
)
定义单例对象管理登录用户:
kotlin
object UserManager {
private var currentUser: User? = null
fun login(user: User) {
currentUser = user
println("登录成功:${user.username}")
}
fun logout() {
currentUser = null
println("已退出登录")
}
fun isLogin(): Boolean {
return currentUser != null
}
fun getUserName(): String {
return currentUser?.username ?: "游客"
}
}
使用:
kotlin
fun main() {
val user = User(
id = 1,
username = "admin",
token = "abc123"
)
UserManager.login(user)
if (UserManager.isLogin()) {
println("当前用户:${UserManager.getUserName()}")
}
UserManager.logout()
}
输出结果:
text
登录成功:admin
当前用户:admin
已退出登录
二、接口 interface
1. 什么是接口?
在 Kotlin 中,接口使用 interface 关键字定义。
接口可以理解为一种规范或能力描述。它本身不负责创建对象,而是规定某个类应该具备哪些功能。
简单理解:
text
接口定义规则,类负责实现规则。
基本格式:
kotlin
interface 接口名 {
fun 方法名()
}
示例:
kotlin
interface UserAction {
fun login()
fun logout()
}
这个接口表示:只要某个类实现了 UserAction,它就应该具备登录和退出登录的能力。
2. 实现接口
类实现接口时,使用 :。
kotlin
class User : UserAction {
override fun login() {
println("用户登录")
}
override fun logout() {
println("用户退出登录")
}
}
完整示例:
kotlin
interface UserAction {
fun login()
fun logout()
}
class User : UserAction {
override fun login() {
println("用户登录")
}
override fun logout() {
println("用户退出登录")
}
}
fun main() {
val user = User()
user.login()
user.logout()
}
输出结果:
text
用户登录
用户退出登录
重点说明:
| 代码 | 说明 |
|---|---|
interface UserAction |
定义接口 |
class User : UserAction |
User 类实现接口 |
override fun login() |
重写接口中的方法 |
override fun logout() |
重写接口中的方法 |
3. 接口方法默认没有方法体
接口中的方法默认只有声明,没有具体实现。
kotlin
interface LoginCallback {
fun onSuccess()
fun onFailed(message: String)
}
实现类必须重写这些方法:
kotlin
class LoginHandler : LoginCallback {
override fun onSuccess() {
println("登录成功")
}
override fun onFailed(message: String) {
println("登录失败:$message")
}
}
4. 接口可以有默认实现
Kotlin 的接口方法可以写默认实现。
kotlin
interface UserAction {
fun login()
fun logout() {
println("默认退出登录")
}
}
实现类只需要实现没有默认方法体的方法:
kotlin
class User : UserAction {
override fun login() {
println("用户登录")
}
}
使用:
kotlin
fun main() {
val user = User()
user.login()
user.logout()
}
输出结果:
text
用户登录
默认退出登录
如果实现类想修改默认实现,也可以重写:
kotlin
class User : UserAction {
override fun login() {
println("用户登录")
}
override fun logout() {
println("自定义退出登录")
}
}
5. 接口中可以定义属性
接口中不仅可以定义方法,也可以定义属性。
kotlin
interface UserInfo {
val username: String
fun printUserName()
}
实现类需要实现这个属性:
kotlin
class User : UserInfo {
override val username: String = "张三"
override fun printUserName() {
println("用户名:$username")
}
}
完整示例:
kotlin
interface UserInfo {
val username: String
fun printUserName()
}
class User : UserInfo {
override val username: String = "张三"
override fun printUserName() {
println("用户名:$username")
}
}
fun main() {
val user = User()
user.printUserName()
}
输出结果:
text
用户名:张三
6. 接口属性不能直接保存状态
接口中的属性一般只是声明,不直接保存数据。
kotlin
interface UserInfo {
val username: String
}
它只是要求实现类必须提供 username。
实现类负责真正保存数据:
kotlin
class User : UserInfo {
override val username: String = "张三"
}
接口中可以写属性的 getter:
kotlin
interface UserInfo {
val username: String
get() = "默认用户"
}
class User : UserInfo
fun main() {
val user = User()
println(user.username)
}
输出结果:
text
默认用户
7. 一个类可以实现多个接口
Kotlin 中一个类只能继承一个父类,但是可以实现多个接口。
kotlin
interface LoginAction {
fun login()
}
interface LogoutAction {
fun logout()
}
class User : LoginAction, LogoutAction {
override fun login() {
println("用户登录")
}
override fun logout() {
println("用户退出登录")
}
}
fun main() {
val user = User()
user.login()
user.logout()
}
输出结果:
text
用户登录
用户退出登录
8. 接口和继承一起使用
如果一个类既继承父类,又实现接口,父类要写在前面,接口写在后面。
kotlin
open class BaseActivity {
fun showLoading() {
println("显示加载中")
}
}
interface LoginCallback {
fun onLoginSuccess()
fun onLoginFailed(message: String)
}
class LoginActivity : BaseActivity(), LoginCallback {
override fun onLoginSuccess() {
println("登录成功")
}
override fun onLoginFailed(message: String) {
println("登录失败:$message")
}
}
其中:
| 代码 | 说明 |
|---|---|
BaseActivity() |
继承父类 |
LoginCallback |
实现接口 |
9. 接口常用于回调
在 Android 开发中,接口最常见的用途之一就是回调。
比如登录功能执行完成后,需要告诉外部登录成功还是失败。
定义接口:
kotlin
interface LoginCallback {
fun onSuccess()
fun onFailed(message: String)
}
登录类:
kotlin
class LoginManager {
fun login(username: String, password: String, callback: LoginCallback) {
if (username == "admin" && password == "123456") {
callback.onSuccess()
} else {
callback.onFailed("用户名或密码错误")
}
}
}
使用:
kotlin
fun main() {
val loginManager = LoginManager()
loginManager.login("admin", "123456", object : LoginCallback {
override fun onSuccess() {
println("登录成功")
}
override fun onFailed(message: String) {
println("登录失败:$message")
}
})
}
输出结果:
text
登录成功
这里的逻辑是:
text
LoginManager 负责执行登录
LoginCallback 负责把登录结果回调给调用方
10. 匿名对象实现接口
如果接口只在某个地方临时使用,可以使用匿名对象实现接口。
kotlin
val callback = object : LoginCallback {
override fun onSuccess() {
println("登录成功")
}
override fun onFailed(message: String) {
println("登录失败:$message")
}
}
这种写法在 Android 早期点击事件和回调中非常常见。
11. Android 点击事件中的接口思想
Android 中的点击事件本质上就是接口回调。
传统写法:
kotlin
button.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
println("按钮被点击")
}
})
这里的 View.OnClickListener 就是一个接口。
Kotlin 中通常简写成 Lambda:
kotlin
button.setOnClickListener {
println("按钮被点击")
}
虽然写法变短了,但本质仍然是接口回调思想。
12. 自定义列表点击接口
在 Android 的 RecyclerView 中,经常会自定义点击接口。
定义接口:
kotlin
interface OnItemClickListener {
fun onItemClick(position: Int)
}
Adapter 中使用:
kotlin
class UserAdapter(
private val userList: List<String>
) {
private var listener: OnItemClickListener? = null
fun setOnItemClickListener(listener: OnItemClickListener) {
this.listener = listener
}
fun simulateItemClick(position: Int) {
listener?.onItemClick(position)
}
}
调用:
kotlin
fun main() {
val adapter = UserAdapter(listOf("张三", "李四", "王五"))
adapter.setOnItemClickListener(object : OnItemClickListener {
override fun onItemClick(position: Int) {
println("点击了第 $position 项")
}
})
adapter.simulateItemClick(1)
}
输出结果:
text
点击了第 1 项
13. 接口可以配合 Lambda 简化
如果接口中只有一个抽象方法,这类接口可以设计成函数类型或 fun interface。
使用普通函数类型
kotlin
class UserAdapter(
private val userList: List<String>
) {
private var onItemClick: ((Int) -> Unit)? = null
fun setOnItemClickListener(listener: (Int) -> Unit) {
onItemClick = listener
}
fun simulateItemClick(position: Int) {
onItemClick?.invoke(position)
}
}
使用:
kotlin
val adapter = UserAdapter(listOf("张三", "李四", "王五"))
adapter.setOnItemClickListener { position ->
println("点击了第 $position 项")
}
adapter.simulateItemClick(1)
这种写法在 Kotlin 中更常见。
使用 fun interface
Kotlin 也支持 fun interface,表示函数式接口。
kotlin
fun interface OnItemClickListener {
fun onItemClick(position: Int)
}
使用时可以简写成 Lambda:
kotlin
val listener = OnItemClickListener { position ->
println("点击了第 $position 项")
}
14. 接口和抽象类的区别
接口和抽象类都可以定义规范,但它们的使用场景不同。
| 对比项 | 接口 interface | 抽象类 abstract class |
|---|---|---|
| 关键字 | interface |
abstract class |
| 是否可以多实现 | 可以实现多个接口 | 只能继承一个抽象类 |
| 是否可以保存状态 | 一般不保存状态 | 可以保存成员变量状态 |
| 构造函数 | 没有构造函数 | 可以有构造函数 |
| 适合场景 | 定义能力、行为规范 | 定义一类对象的共同基础 |
| Android 常见用途 | 点击回调、事件监听、能力抽象 | BaseActivity、BaseFragment、BaseRepository |
简单理解:
text
接口表示"能做什么"
抽象类表示"是什么"
示例:
kotlin
abstract class Person {
abstract fun eat()
}
interface LoginAction {
fun login()
}
class User : Person(), LoginAction {
override fun eat() {
println("用户吃饭")
}
override fun login() {
println("用户登录")
}
}
15. 接口在 Android 中的常见使用场景
| 场景 | 示例 |
|---|---|
| 点击事件回调 | OnClickListener |
| 列表 Item 点击 | OnItemClickListener |
| 登录结果回调 | LoginCallback |
| 网络请求结果回调 | RequestCallback |
| 权限申请结果回调 | PermissionCallback |
| 模块间通信 | OnDataChangedListener |
| 功能能力抽象 | Downloadable、Payable |
| MVP 架构 | View 接口、Presenter 接口 |
16. 网络请求回调示例
定义接口:
kotlin
interface RequestCallback {
fun onSuccess(data: String)
fun onError(error: String)
}
请求类:
kotlin
class ApiService {
fun requestData(callback: RequestCallback) {
val success = true
if (success) {
callback.onSuccess("这是服务器返回的数据")
} else {
callback.onError("网络请求失败")
}
}
}
使用:
kotlin
fun main() {
val apiService = ApiService()
apiService.requestData(object : RequestCallback {
override fun onSuccess(data: String) {
println("请求成功:$data")
}
override fun onError(error: String) {
println("请求失败:$error")
}
})
}
输出结果:
text
请求成功:这是服务器返回的数据
17. 权限申请回调示例
定义接口:
kotlin
interface PermissionCallback {
fun onGranted()
fun onDenied()
}
使用:
kotlin
class PermissionManager {
fun requestPermission(callback: PermissionCallback) {
val granted = true
if (granted) {
callback.onGranted()
} else {
callback.onDenied()
}
}
}
调用:
kotlin
fun main() {
val manager = PermissionManager()
manager.requestPermission(object : PermissionCallback {
override fun onGranted() {
println("权限申请成功")
}
override fun onDenied() {
println("权限被拒绝")
}
})
}
18. 接口命名建议
接口命名要能表达它的作用。
| 类型 | 命名示例 |
|---|---|
| 点击事件 | OnItemClickListener |
| 长按事件 | OnItemLongClickListener |
| 登录回调 | LoginCallback |
| 请求回调 | RequestCallback |
| 权限回调 | PermissionCallback |
| 下载能力 | Downloadable |
| 支付能力 | Payable |
| 加载能力 | Loadable |
| 刷新能力 | Refreshable |
一般来说:
text
事件监听类接口常用 Listener 结尾
结果回调类接口常用 Callback 结尾
能力描述类接口常用 able 结尾
例如:
kotlin
interface Clickable {
fun click()
}
interface Downloadable {
fun download()
}
interface LoginCallback {
fun onSuccess()
fun onFailed(message: String)
}
19. 接口使用建议
在 Android Kotlin 开发中,可以遵循以下建议:
| 建议 | 说明 |
|---|---|
| 接口只定义必要方法 | 不要把接口设计得过大 |
| 一个接口只表达一种能力 | 比如登录、下载、点击分开定义 |
| 回调接口命名清晰 | 如 LoginCallback、RequestCallback |
| 单方法接口优先考虑 Lambda | Kotlin 中可以减少模板代码 |
| 多状态回调可以用多个方法 | 如 onSuccess()、onError() |
| 状态复杂时可考虑密封类 | 比多个回调方法更清晰 |
| 接口适合解耦 | 调用方不依赖具体实现类 |
20. 完整示例:登录接口回调
kotlin
interface LoginCallback {
fun onSuccess(username: String)
fun onFailed(message: String)
}
class LoginManager {
fun login(
username: String,
password: String,
callback: LoginCallback
) {
if (username.isBlank()) {
callback.onFailed("用户名不能为空")
return
}
if (password.isBlank()) {
callback.onFailed("密码不能为空")
return
}
if (username == "admin" && password == "123456") {
callback.onSuccess(username)
} else {
callback.onFailed("用户名或密码错误")
}
}
}
fun main() {
val loginManager = LoginManager()
loginManager.login(
username = "admin",
password = "123456",
callback = object : LoginCallback {
override fun onSuccess(username: String) {
println("登录成功,欢迎 $username")
}
override fun onFailed(message: String) {
println("登录失败:$message")
}
}
)
}
输出结果:
text
登录成功,欢迎 admin
21. 使用 Lambda 优化登录回调
如果只是简单回调,也可以不用接口,直接使用函数类型。
kotlin
class LoginManager {
fun login(
username: String,
password: String,
onSuccess: (String) -> Unit,
onFailed: (String) -> Unit
) {
if (username.isBlank()) {
onFailed("用户名不能为空")
return
}
if (password.isBlank()) {
onFailed("密码不能为空")
return
}
if (username == "admin" && password == "123456") {
onSuccess(username)
} else {
onFailed("用户名或密码错误")
}
}
}
调用:
kotlin
fun main() {
val loginManager = LoginManager()
loginManager.login(
username = "admin",
password = "123456",
onSuccess = { username ->
println("登录成功,欢迎 $username")
},
onFailed = { message ->
println("登录失败:$message")
}
)
}
这种写法在 Kotlin 中更简洁。
三、类、对象和接口使用建议
在 Android Kotlin 开发中,可以遵循以下建议:
| 场景 | 推荐写法 |
|---|---|
| 保存数据 | data class |
| 工具类 | object |
| 全局配置 | object 或 companion object |
| 页面类 | Activity / Fragment |
| 页面数据管理 | ViewModel |
| 数据仓库 | Repository |
| 固定状态 | enum class |
| 页面状态 | sealed class |
| 事件回调 | interface 或 Lambda |
| 可复用父类 | open class 或 abstract class |
四、最终总结
Kotlin 中使用 class 定义类:
kotlin
class User {
var name: String = ""
var age: Int = 0
}
使用类创建对象:
kotlin
val user = User()
访问对象属性和方法:
kotlin
user.name = "张三"
user.age = 18
Kotlin 中使用 interface 定义接口:
kotlin
interface LoginCallback {
fun onSuccess()
fun onFailed(message: String)
}
类实现接口:
kotlin
class LoginManager : LoginCallback {
override fun onSuccess() {
println("成功")
}
override fun onFailed(message: String) {
println("失败:$message")
}
}
常见类相关语法:
| 语法 | 作用 |
|---|---|
class |
定义普通类 |
data class |
定义数据类 |
object |
定义单例对象 |
companion object |
定义伴生对象,类似静态成员 |
open class |
允许类被继承 |
abstract class |
定义抽象类 |
interface |
定义接口 |
enum class |
定义枚举类 |
sealed class |
定义密封类,表示有限状态 |
inner class |
定义内部类 |
constructor |
定义构造函数 |
init |
初始化代码块 |
this |
表示当前对象 |
override |
重写父类或接口方法 |
最后记住两句话:
text
类是对象的模板,对象是类的具体实例。
接口定义"应该做什么",具体类负责"怎么做"。
在 Android Kotlin 开发中,掌握类、对象和接口之后,就可以更好地理解 Activity、Fragment、ViewModel、Adapter、Repository、事件回调等核心开发方式。