在 Kotlin 中,class
、data class
、internal class
、abstract class
、open class
、sealed class
和 inner class
都是不同类型的类,各自有其独特的用途和特性,下面为你详细介绍它们的区别:
1. class
(普通类)
class
是 Kotlin 中定义类的基本关键字,用于创建常规的类。普通类可以包含属性、方法、构造函数等,并且可以继承其他类、实现接口。
登录后复制
kotlin
// 定义一个普通类
class Person(val name: String, var age: Int) {
fun introduce() {
println("My name is $name and I'm $age years old.")
}
}
fun main() {
val person = Person("Alice", 25)
person.introduce()
}
特点:
- 可以定义各种类型的成员,如属性、方法、嵌套类等。
- 可以有自定义的构造函数和初始化块。
- 可以继承其他类和实现接口。
2. data class
(数据类)
data class
是一种特殊的类,主要用于保存数据。Kotlin 会自动为数据类生成一些有用的方法,如 equals()
、hashCode()
、toString()
和 copy()
等。
登录后复制
kotlin
// 定义一个数据类
data class User(val id: Int, val name: String, val email: String)
fun main() {
val user1 = User(1, "Bob", "[email protected]")
val user2 = User(1, "Bob", "[email protected]")
println(user1) // 自动生成的 toString() 方法
println(user1 == user2) // 自动生成的 equals() 方法
val user3 = user1.copy(name = "Charlie") // 自动生成的 copy() 方法
println(user3)
}
特点:
- 自动生成
equals()
、hashCode()
、toString()
和copy()
方法。 - 主构造函数至少需要一个参数,且所有参数必须标记为
val
或var
。 - 数据类不能是
abstract
、open
、sealed
或inner
的。
3. internal class
(内部类)
internal class
是使用 internal
修饰符修饰的类,它的访问权限是模块级别的。也就是说,internal
类只能在同一个模块内被访问。
登录后复制
kotlin
// 定义一个内部类
internal class DatabaseHelper {
fun connect() {
println("Connecting to the database...")
}
}
// 在同一个模块内可以访问
fun main() {
val helper = DatabaseHelper()
helper.connect()
}
特点:
- 访问权限是模块级别的,同一个模块内的代码可以访问
internal
类。 - 可以包含各种类型的成员,如属性、方法、嵌套类等。
4. abstract class
(抽象类)
抽象类是用 abstract
修饰符修饰的类,不能被实例化,主要用于作为其他类的基类。抽象类可以包含抽象方法(没有具体实现的方法),子类必须实现这些抽象方法。
登录后复制
kotlin
abstract class Shape {
abstract fun area(): Double
}
class Circle(val radius: Double) : Shape() {
override fun area() = Math.PI * radius * radius
}
特点:
- 不能被实例化。
- 可包含抽象方法和具体方法。
- 子类必须实现抽象类中的所有抽象方法。
5. open class
(开放类)
开放类是用 open
修饰符修饰的类,与普通类不同,开放类可以被继承。在 Kotlin 中,类默认是 final
的,若要让类能被继承,就需要使用 open
关键字。
登录后复制
kotlin
open class Animal {
open fun makeSound() {
println("Some sound")
}
}
class Dog : Animal() {
override fun makeSound() {
println("Bark")
}
}
特点:
- 可以被继承。
- 类中的方法和属性默认是
final
的,若要让它们能被重写,也需要使用open
关键字。
6. sealed class
(密封类)
密封类是用 sealed
修饰符修饰的类,它是一种特殊的抽象类,用于表示受限的类层次结构。密封类的所有子类都必须在与密封类相同的文件中声明:
登录后复制
kotlin
sealed class Result {
class Success(val data: String) : Result()
class Error(val message: String) : Result()
}
fun handleResult(result: Result) {
when (result) {
is Result.Success -> println("Success: ${result.data}")
is Result.Error -> println("Error: ${result.message}")
}
}
特点:
- 用于表示受限的类层次结构。
- 所有子类必须在与密封类相同的文件中声明。
- 在
when
表达式中使用密封类时,不需要else
分支。
7. inner class
(内部类)
内部类是定义在另一个类内部的类,使用 inner
关键字修饰。内部类可以访问外部类的成员,包括私有成员。
登录后复制
kotlin
class Outer {
private val outerValue = 10
inner class Inner {
fun printOuterValue() {
println(outerValue)
}
}
}
fun main() {
val outer = Outer()
val inner = outer.Inner()
inner.printOuterValue()
}
特点:
- 可以访问外部类的成员,包括私有成员。
- 内部类会持有一个对外部类实例的引用。
总结
- class:用于创建常规类,默认不可被继承。
- data class:主要用于保存数据,自动生成常用方法。
- internal class:访问权限为模块级别。
- abstract class:不能被实例化,可包含抽象方法,子类需实现抽象方法。
- open class:可以被继承,类和成员默认不可重写,需用
open
修饰。 - sealed class:表示受限的类层次结构,子类需在同一文件中声明。
- inner class:定义在另一个类内部,可访问外部类成员。