Swift 中的类(Class)是引用类型(Reference Type),用于创建具有继承、引用语义、身份比较等特性的对象。它适合建模复杂对象、控制器、共享状态等场景。
基本语法
class 类名: 超类?, 协议1, 协议2... {
// 属性
var property: Type
let constant: Type
// 初始化器
init(parameters) { ... }
// 析构器
deinit { ... }
// 方法
func method() { ... }
}
示例:车辆类
class Vehicle {
var numberOfWheels: Int
var currentSpeed: Double = 0.0
init(wheels: Int) {
self.numberOfWheels = wheels
}
func accelerate(by amount: Double) {
currentSpeed += amount
}
func description() -> String {
return "这辆车有 \(numberOfWheels) 个轮子,当前速度 \(currentSpeed) km/h"
}
}
// 继承
class Bicycle: Vehicle {
var hasBasket = false
init(hasBasket: Bool = false) {
self.hasBasket = hasBasket
super.init(wheels: 2)
self.currentSpeed = 0
}
override func description() -> String {
return super.description() + (hasBasket ? ",带篮子" : "")
}
}
let bike = Bicycle(hasBasket: true)
bike.accelerate(by: 15)
print(bike.description())
// 这辆车有 2 个轮子,当前速度 15.0 km/h,带篮子
核心特性对比(类 vs 结构体)
| 特性 | 类 | 结构体 |
|---|---|---|
| 类型 | 引用类型 | 值类型 |
| 赋值 | 共享引用 | 复制副本 |
| 继承 | 支持 | 不支持 |
析构器 deinit | 支持 | 不支持 |
身份比较 === | 支持 | 不支持 |
| 内存管理 | ARC 自动引用计数 | 栈/堆(Copy-on-Write) |
| 多态 | 支持 | 不支持 |
1. 引用语义(关键!)
class Person {
var name: String
init(name: String) { self.name = name }
func sayHello() { print("Hi, I'm \(name)") }
}
let p1 = Person(name: "Alice")
let p2 = p1 // 同一个对象!
p2.name = "Bob"
p1.sayHello() // Hi, I'm Bob
print(p1 === p2) // true(同一实例)
结构体则会复制:
struct Point { var x = 0, y = 0 }
var s1 = Point(x: 1, y: 2)
var s2 = s1
s2.x = 99
print(s1.x) // 1(独立副本)
2. 初始化器(Initializer)
指定初始化器(Designated)
class User {
var id: Int
var name: String
init(id: Int, name: String) {
self.id = id
self.name = name
}
}
便利初始化器(Convenience)
class User {
var id: Int
var name: String
init(id: Int, name: String) {
self.id = id
self.name = name
}
convenience init(name: String) {
self.init(id: 0, name: name)
}
}
let user = User(name: "Tom") // 使用便利初始化器
两阶段初始化(Two-Phase Initialization)
- 初始化所有存储属性(包括继承的)
- 调用
super.init
class Animal {
var species: String
init(species: String) { self.species = species }
}
class Dog: Animal {
var breed: String
init(breed: String) {
self.breed = breed // 第1阶段:初始化自身属性
super.init(species: "Canine") // 第2阶段:调用父类
}
}
3. 析构器(deinit)
class FileHandler {
let filename: String
init(filename: String) {
self.filename = filename
print("打开文件: \(filename)")
}
deinit {
print("关闭文件: \(filename)")
}
}
var file: FileHandler? = FileHandler(filename: "data.txt")
file = nil // 触发 deinit
// 打开文件: data.txt
// 关闭文件: data.txt
结构体无
deinit
4. 方法重写(Override)
class Shape {
func draw() -> String {
return "绘制形状"
}
}
class Circle: Shape {
var radius: Double
init(radius: Double) { self.radius = radius }
override func draw() -> String {
return "绘制圆,半径 \(radius)"
}
}
5. 属性重写
class Car {
var speed: Double { 0 }
}
class SportsCar: Car {
private var _speed = 200.0
override var speed: Double {
get { _speed }
set { _speed = min(newValue, 300) }
}
}
6. 类型属性和方法
class Math {
static let pi = 3.14159
class func square(_ x: Double) -> Double {
return x * x
}
}
print(Math.pi)
print(Math.square(5)) // 25.0
class func可被子类重写,static func不可
7. 引用循环与弱引用
class Person {
var name: String
var apartment: Apartment?
init(name: String) { self.name = name }
deinit { print("\(name) 被释放") }
}
class Apartment {
var number: Int
weak var tenant: Person? // weak 打破循环
// unowned var tenant: Person? // 另一种方式
init(number: Int) { self.number = number }
deinit { print("公寓 \(number) 被释放") }
}
var john: Person? = Person(name: "John")
var unit4A: Apartment? = Apartment(number: 4)
john?.apartment = unit4A
unit4A?.tenant = john
john = nil
unit4A = nil
// John 被释放
// 公寓 4 被释放
无
weak/unowned会导致内存泄漏
8. final 关键字
final class ImmutablePoint {
let x: Double
let y: Double
init(x: Double, y: Double) {
self.x = x
self.y = y
}
}
// 不能被继承
9. 类与协议
protocol Resettable {
func reset()
}
class Counter: Resettable {
var count = 0
func reset() { count = 0 }
}
10. AnyObject 和类型转换
class Animal { }
class Dog: Animal { func bark() { print("Woof") } }
class Cat: Animal { func meow() { print("Meow") } }
let pets: [AnyObject] = [Dog(), Cat(), Dog()]
for pet in pets {
if let dog = pet as? Dog {
dog.bark()
}
}
最佳实践总结
| 场景 | 推荐使用类 |
|---|---|
| 需要继承 | 类 |
| 需要引用语义(共享状态) | 类 |
需要 deinit 清理资源 | 类 |
实现 Cocoa 框架(如 UIViewController) | 类 |
身份重要(=== 比较) | 类 |
| 场景 | 推荐使用结构体 |
|---|---|
| 简单数据模型 | 结构体 |
| 复制安全 | 结构体 |
| 无继承需求 | 结构体 |
| 性能敏感 | 结构体 |
常见面试题
- 类和结构体的赋值行为有何不同?
→ 类是引用传递(共享),结构体是值复制(独立)。 - 如何防止引用循环?
→ 使用weak或unowned引用。 - 什么时候用
unownedvsweak?
weak: 可选,可能为nilunowned: 必有值,生命周期明确,不为nil
class funcvsstatic func?
class func: 可被子类重写static func: 不可重写
小技巧
// 单例模式
class AudioManager {
static let shared = AudioManager()
private init() { } // 防止外部创建
}
// 延迟初始化
class DataService {
lazy var database = Database()
}
高级话题(可继续提问)
- 值类型 vs 引用类型的 Copy-on-Write 优化
- Actor 模型(并发安全类)
- 类簇(Class Cluster)
- KVO / Notification 与类
- SwiftUI 中的
@Observable类
需要代码示例、性能分析、或与 Actor 对比?欢迎继续提问!