Kotlin学习笔记(7)--类与对象
类
Kotlin 是一门面向对象的编程语言,支持类和对象的创建与管理。
类的定义
在 Kotlin 中,使用 class 关键字定义类。类可以包含构造函数、属性、方法、嵌套类等。
class Person {
var name: String = ""
var age: Int = 0
fun greet() {
println("Hello, my name is $name and I am $age years old.")
}
}
注:如果一个类只有方法,没有具体的构造函数参数、初始化块或额外的成员声明,那么在定义类时可以省略花括号 {},例如:
class Person {
fun greet() {
println("Hello, my name is $name and I am $age years old.")
}
}
实例化对象
要使用类,需要实例化它的对象:
val person = Person()
person.name = "Alice"
person.age = 25
构造器
类可以有主构造器和一个或多个次构造器。
主构造器
Kotlin 将构造函数直接集成在类定义中:
class Person(val name: String, var age: Int)
实例化:
val person = Person("Alice", 25)
初始化代码块
init 块用于类的初始化时执行代码:
class Person(val name: String, var age: Int) {
init {
println("Person initialized with name: $name and age: $age")
}
}
次构造器
如果类需要多个构造函数,可以定义次构造函数
class Person {
var name: String
var age: Int
constructor(name: String) {
this.name = name
this.age = 0
}
constructor(name: String, age: Int) {
this.name = name
this.age = age
}
}
fun main() {
val person1 = Person("Alice")
val person2 = Person("Bob", 30)
}
注意: 如果类有主构造器,则每个次构造器需要委托给主构造器。
class Rectangle(val width: Int, val height: Int) {
constructor(size: Int) : this(size, size)
}
类的继承
Kotlin 中类默认是 final 的,需要加上 open 关键字才能被继承:
open class Animal {
open fun sound() {
println("Animal sound")
}
}
class Dog : Animal() {
override fun sound() {
println("Dog barks")
}
}
抽象类
抽象类是不能被实例化的类,通常用于定义接口和共享代码。
abstract class Animal(
var name: String
) {
init {
println("这只动物的名字是 $name")
}
abstract fun makeSound()
}
class Dog : Animal("Dog") {
override fun makeSound() {
println("汪汪")
}
}
class Cat : Animal("Cat") {
override fun makeSound() {
println("喵喵")
}
}
fun main() {
val dog = Dog()
dog.makeSound() // 输出: 汪汪
val cat = Cat()
cat.makeSound() // 输出: 喵喵
}
嵌套类
嵌套类是在另一个类内部定义的类,但它不持有外部类的引用。
class Outer {
private val bar = "外部类属性"
class Nested {
fun foo() = "嵌套类方法"
}
}
fun main() {
val nested = Outer.Nested()
println(nested.foo()) // 输出: 嵌套类方法
}
内部类
内部类使用 inner 关键字声明,可以访问外部类的成员。
class Outer {
private val bar = "外部类属性"
inner class Inner {
fun foo() = bar
}
}
fun main() {
val outer = Outer()
val inner = outer.Inner()
println(inner.foo()) // 输出: 外部类属性
}
匿名内部类
匿名内部类用于创建没有名称的类的实例,常用于实现接口或继承抽象类。
abstract class Animal(val name: String) {
abstract fun makeSound()
}
fun main() {
val bear = object : Animal("Bear") {
override fun makeSound() {
println("吼叫!")
}
}
bear.makeSound() // 输出: 吼叫!
}
密封类
在密封类中,所有的子类都必须在密封类的同一个文件中定义。这种特性使得在处理不同类型的子类时更加安全和便捷,尤其适用于表示状态或结果的场景,如网络请求的成功与失败状态。
sealed class Result
class Success(val data: String) : Result()
class Failure(val error: String) : Result()
数据类
数据类用于存储数据,并自动生成常见的函数(equals、hashCode、toString 等):
data class User(val name: String, val age: Int)
类的修饰符
Kotlin 支持多种修饰符,用于控制类的可见性和行为。
open:允许类被继承。默认情况下,类是final的,不能被继承。abstract:声明一个抽象类,不能被实例化。final:默认修饰符,类不能被继承。sealed:限制类的继承范围,适用于表示受限的类层次结构。data:用于数据类,自动生成equals(),hashCode(),toString(),copy()等方法。enum:用于枚举类,表示固定的常量集合。
示例:
// 可继承的类
open class Vehicle(val make: String)
// 数据类
data class User(val name: String, val age: Int)
// 枚举类
enum class Direction {
NORTH, SOUTH, EAST, WEST
}
接口
Kotlin 的接口(Interface)是定义一组方法和属性的蓝图,任何类都可以实现这些接口,从而确保类具备特定的行为和特性。接口在 Kotlin 中提供了一种灵活的方式来实现多重继承,并允许代码的高复用性和可维护性。
定义接口
在 Kotlin 中,使用 interface 关键字来定义接口。接口可以包含抽象方法、属性以及方法的默认实现。
interface Drivable {
// 抽象属性
val maxSpeed: Int
// 抽象方法
fun drive()
// 有默认实现的方法
fun brake() {
println("The vehicle is braking.")
}
}
实现接口
类通过冒号 : 来实现一个或多个接口。如果接口中有抽象成员,类需要提供这些成员的具体实现;对于有默认实现的方法,类可以选择重写它们,也可以直接使用默认实现。
class Car(override val maxSpeed: Int) : Drivable {
override fun drive() {
对象
对象表达式
对象表达式用于创建匿名对象:
val obj = object {
var x: Int = 10
var y: Int = 20
}
println(obj.x + obj.y) // 输出:30
对象声明
对象声明用于创建单例对象,类似于Java的静态类:
object Singleton {
var name: String = "Singleton"
fun printName() {
println(name)
}
}
调用:
Singleton.printName() // 输出:Singleton
伴生对象
Kotlin 中的伴生对象(Companion Object)是用于在类内部定义与类本身相关联的对象。它们提供了一种替代 Java 中静态成员的方式,使得在 Kotlin 中实现类似静态方法和属性的功能成为可能。
伴生对象的定义
使用 companion object 关键字用于声明一个伴生对象。每个类最多只能有一个伴生对象。伴生对象的成员可以通过类名直接访问,就像 Java 中的静态成员一样。
class MyClass {
companion object {
fun create(): MyClass = MyClass()
}
}
MyClass 类有一个伴生对象,其中定义了一个 create 方法,用于创建 MyClass 的实例。
伴生对象的命名
默认情况下,伴生对象没有名称,但也可以为它指定一个名称:
class MyClass {
companion object Factory {
fun create(): MyClass = MyClass()
}
}
通过给伴生对象命名(例如上面的 Factory),可以更明确地引用它:
val instance = MyClass.Factory.create()
如果没有命名,可以直接使用类名访问:
val instance = MyClass.create()
访问伴生对象的成员
伴生对象的成员可以像静态成员一样通过类名访问:
class MyClass {
companion object {
const val CONSTANT = "SomeConstant"
fun printConstant() {
println(CONSTANT)
}
}
}
fun main() {
println(MyClass.CONSTANT) // 输出: SomeConstant
MyClass.printConstant() // 输出: SomeConstant
}
使用伴生对象实现工厂模式
伴生对象常用于实现工厂模式,通过定义工厂方法来创建类的实例:
class User private constructor(val name: String) {
companion object {
fun create(name: String): User {
// 可以在这里添加创建实例的逻辑,如验证、缓存等
return User(name)
}
}
}
fun main() {
val user = User.create("Alice")
println(user.name) // 输出: Alice
}
User类的构造函数被声明为private,这意味着外部无法直接创建实例。相反,必须通过伴生对象的create方法来创建User的实例。
伴生对象实现接口
伴生对象还可以实现接口
interface Factory<T> {
fun create(): T
}
class MyClass {
companion object : Factory<MyClass> {
override fun create(): MyClass = MyClass()
}
}
fun main() {
val factory: Factory<MyClass> = MyClass
val instance = factory.create()
}
- 伴生对象实现了 Factory 接口,这使得它可以被用作工厂实例。
扩展伴生对象
还可以为伴生对象定义扩展函数和属性:
class MyClass {
companion object
}
fun MyClass.Companion.greet() {
println("Hello from companion object!")
}
fun main() {
MyClass.greet() // 输出: Hello from companion object!
}

浙公网安备 33010602011771号