类(Class)
类(Class) 是面向对象编程的核心概念之一,它提供了一种创建复杂数据结构和行为的蓝图。下面我将从基础概念到实际应用全面解析 Swift 中的类:
一、类是什么?
类是一个自定义的数据类型,它定义了:
-
属性(Properties):存储数据的变量/常量(如人的姓名、年龄)
-
方法(Methods):操作数据的函数(如人的行走、说话)
-
初始化器(Initializers):创建实例的特殊方法(
init) -
反初始化器(Deinitializers):清理资源的特殊方法(
deinit) -
// 类的基本定义 class Person { // 属性 var name: String var age: Int // 初始化器 init(name: String, age: Int) { self.name = name self.age = age } // 方法 func introduce() { print("你好,我叫\(name),今年\(age)岁。") } } // 创建实例 let person = Person(name: "张三", age: 30) person.introduce() // 输出:你好,我叫张三,今年30岁。
二、类的作用(为什么需要类?)
| 作用 | 说明 | 示例 |
|---|---|---|
| 封装数据 | 将相关数据和操作绑定在一起 | 把人的属性和行为封装在Person类中 |
| 代码复用 | 通过继承共享代码 | Student类继承Person的所有特性 |
| 抽象建模 | 表示现实世界实体 | 用Car类表示汽车的属性和行为 |
| 管理状态 | 维护对象生命周期状态 | 用deinit释放资源 |
| 实现多态 | 不同对象响应相同消息 | 不同子类实现自己的draw()方法 |
三、类与结构体(struct)的关键区别
| 特性 | 类(Class) | 结构体(Struct) |
|---|---|---|
| 类型 | 引用类型 | 值类型 |
| 继承 | ✅ 支持 | ❌ 不支持 |
| 反初始化器 | ✅ 有deinit | ❌ 没有 |
| 内存管理 | 引用计数(ARC) | 栈上分配(通常) |
| 可变性 | 方法可修改属性(无需mutating) | 需mutating关键字 |
| 身份比较 | 可用===运算符 | 只能比较值 |
class ClassExample { var value = 0 }
struct StructExample { var value = 0 }
var a = ClassExample()
var b = a // b和a引用同一个实例
b.value = 10
print(a.value) // 输出:10(值被改变)
var c = StructExample()
var d = c // d是c的副本
d.value = 20
print(c.value) // 输出:0(原始值未变)
四、类的核心特性
1.继承(Inheritance)
class Student: Person { // 继承Person
var studentID: String
init(name: String, age: Int, studentID: String) {
self.studentID = studentID
super.init(name: name, age: age)
}
// 重写父类方法
override func introduce() {
print("我是学生\(name),学号\(studentID)")
}
}
2.多态(Polymorphism)
let people: [Person] = [
Person(name: "李四", age: 40),
Student(name: "王五", age: 20, studentID: "S12345")
]
for person in people {
person.introduce() // 不同对象调用相同方法产生不同行为
}
/* 输出:
你好,我叫李四,今年40岁。
我是学生王五,学号S12345
*/
3.引用类型(Reference Type)
let student1 = Student(name: "小明", age: 18, studentID: "S1001")
let student2 = student1 // 复制的是引用,不是值
student2.name = "小红"
print(student1.name) // 输出:"小红"(原始对象也被修改)
五、类的使用场景
| 使用场景 | 说明 | 示例 |
|---|---|---|
| 需要继承 | 创建类层次结构 | UI控件:UIView → UIButton → CustomButton |
| 共享状态 | 多个地方访问同一实例 | 单例模式:FileManager.default |
| 生命周期控制 | 需要资源清理 | 网络连接完成后关闭资源(deinit) |
| 标识重要 | 需要跟踪特定实例 | 游戏中的角色对象 |
| 复杂行为 | 需要多态特性 | 支付系统:CreditCard、PayPal实现相同支付接口 |
六、实际应用示例
场景:电商应用中的商品管理
// 基类:商品
class Product {
let id: String
var name: String
var price: Double
init(id: String, name: String, price: Double) {
self.id = id
self.name = name
self.price = price
}
func displayInfo() {
print("商品:\(name),价格:¥\(price)")
}
}
// 子类:折扣商品
class DiscountedProduct: Product {
let discountRate: Double
init(id: String, name: String, price: Double, discountRate: Double) {
self.discountRate = discountRate
super.init(id: id, name: name, price: price)
}
// 计算折后价格
var discountedPrice: Double {
return price * (1 - discountRate)
}
// 重写显示方法
override func displayInfo() {
super.displayInfo()
print("折扣:\(discountRate * 100)%,折后价:¥\(discountedPrice)")
}
}
// 使用
let normalProduct = Product(id: "P001", name: "普通商品", price: 100)
normalProduct.displayInfo()
/* 输出:
商品:普通商品,价格:¥100.0
*/
let specialProduct = DiscountedProduct(id: "P002", name: "特价商品", price: 200, discountRate: 0.3)
specialProduct.displayInfo()
/* 输出:
商品:特价商品,价格:¥200.0
折扣:30.0%,折后价:¥140.0
*/
七、最佳实践建议
-
优先使用结构体:当不需要继承、不需要引用语义时,使用更轻量的结构体
-
使用
final防止继承:如果不希望类被继承,标记为final class -
遵循最小权限原则:
-
属性用
private限制访问 -
方法用
fileprivate限制文件内访问
-
-
内存管理:
-
使用
weak打破强引用循环 -
闭包中使用
[weak self]避免循环引用
-
-
协议导向编程:优先使用协议定义行为,而非类继承
八、何时选择类 vs 结构体
| 选择类 | 选择结构体 |
|---|---|
| 需要继承 | 不需要继承 |
需要deinit清理资源 | 不需要特殊清理 |
| 需要共享修改(引用语义) | 需要值语义(独立副本) |
标识重要(===比较) | 内容重要(==比较) |
| 与Objective-C交互 | 纯Swift环境 |
2018

被折叠的 条评论
为什么被折叠?



