Kotlin面向对象编程
文章说明
本文内容基于Kotlin官方文档总结翻译而成,旨在为自己学习Kotlin使用。文中的代码示例、技术概念和最佳实践均参考自Kotlin官方资源和相关技术文档,如需获取最新或更详细的信息,建议查阅官方文档。
1. 类与对象
Kotlin支持面向对象编程,允许通过类和对象组织代码。类是对象的蓝图,定义对象的属性和行为。
类的定义
在Kotlin中,使用class
关键字声明类:
class Person { |
创建对象
要创建类的实例,直接调用构造函数,无需new
关键字:
val person = Person() |
属性
类的属性可以在类头部的构造函数参数中声明,或在类体中定义:
class Person(val firstName: String, var age: Int) { |
属性可以是只读(val
)或可变(var
):
val
- 只读属性,初始化后不能更改var
- 可变属性,可以更改其值
访问属性
使用点符号(.
)访问类的属性:
val person = Person("John", 25) |
2. 构造函数
Kotlin中的类可以有一个主构造函数和多个次构造函数。
主构造函数
主构造函数是类头部的一部分,直接在类名后声明:
class Person constructor(firstName: String) { |
如果主构造函数没有任何注解或可见性修饰符,可以省略constructor
关键字:
class Person(firstName: String) { |
要使构造函数参数成为属性,需添加val
或var
修饰符:
class Person(val firstName: String, var age: Int) { |
初始化块
初始化块使用init
关键字定义,用于放置初始化代码:
class Person(val name: String) { |
初始化块按照它们在类中出现的顺序执行,与属性初始化交错进行。
次构造函数
次构造函数使用constructor
关键字声明:
class Person(val name: String) { |
次构造函数必须直接或间接委托给主构造函数,使用this
关键字实现委托。
3. 成员函数
类中可以定义函数来表示该类的行为:
class Person(val name: String) { |
调用成员函数:
val person = Person("Alice") |
4. 继承
Kotlin中所有类默认是final
的(不可继承)。要允许类被继承,需使用open
关键字:
基类声明
open class Person(val name: String) { |
派生类声明
要继承一个类,使用冒号后跟基类名称:
class Student( |
继承规则:
- 必须在派生类构造函数中初始化基类
- 要重写基类的方法,基类方法必须标记为
open
- 重写的方法必须使用
override
修饰符
调用超类实现
在派生类中,可以使用super
关键字调用超类的方法:
class Student(name: String, val studentId: String) : Person(name) { |
派生类初始化顺序
在构造派生类实例时,基类的初始化先于派生类进行:
- 基类构造函数的参数被评估
- 基类的初始化块和属性初始化器执行
- 派生类的初始化块和属性初始化器执行
- 派生类构造函数的代码执行
5. 接口
接口定义了类可以实现的行为契约,但不能包含状态。
接口声明
interface Drawable { |
实现接口
类可以实现一个或多个接口:
class Circle : Drawable { |
接口中的属性
接口可以包含抽象属性或带有访问器的属性:
interface Named { |
解决实现冲突
当实现多个接口并遇到方法冲突时,必须明确指定使用哪一个实现:
interface A { |
6. 数据类
数据类专门用于保存数据,编译器会自动生成有用的方法。
声明数据类
data class User(val name: String, val age: Int) |
对于每个数据类,编译器自动生成:
equals()
/hashCode()
- 比较实例的方法toString()
- 格式为 “User(name=John, age=42)”componentN()
- 用于解构声明copy()
- 创建实例副本的方法
使用数据类
val user1 = User("John", 30) |
数据类要求
数据类必须满足以下要求:
- 主构造函数至少有一个参数
- 所有主构造函数参数必须标记为
val
或var
- 数据类不能是抽象的、开放的、密封的或内部的
7. 密封类与接口
密封类提供了对类层次结构的受控继承,所有直接子类在编译时都是已知的。
声明密封类
sealed class Result { |
使用密封类
密封类与when
表达式结合使用时特别有用,可以进行详尽的条件检查:
fun handleResult(result: Result) = when(result) { |
密封类规则
- 密封类的直接子类必须在同一个包和模块中声明
- 子类可以是普通类、数据类或对象
- 子类可以有自己的子类,这些子类可以在任何地方声明
8. 对象表达式与对象声明
Kotlin提供了创建匿名类实例和实现单例模式的便捷方法。
对象表达式(匿名内部类)
对象表达式创建匿名类的实例:
interface OnClickListener { |
匿名对象可以继承多个类或实现多个接口。
对象声明(单例)
对象声明定义了单例类:
object Logger { |
对象声明不能有构造函数,但可以有初始化块。
伴生对象
伴生对象提供了与Java静态成员类似的功能:
class MyClass { |
伴生对象可以实现接口或继承类,也可以拥有自己的名称。
参考链接
- Kotlin官方文档:https://kotlinlang.org/docs/home.html