Swift-static和class

在 Swift 中,staticclass 都用于修饰类型属性,但它们有重要的区别。让我详细解释:

基本定义

static - 静态属性

swift

复制代码
class MyClass {
    static let staticProperty = "我是静态属性"
    static var staticVariable = "我也是静态属性"
}

class - 类属性(仅用于类)

swift

复制代码
class MyClass {
    class var classProperty: String {
        return "我是类属性"
    }
}

主要区别

1. 继承行为不同

static - 不能重写

swift

复制代码
class Parent {
    static let version = "1.0"
    static var name: String { return "Parent" }
}

class Child: Parent {
    // ❌ 编译错误:不能重写静态属性
    // override static let version = "2.0"
    
    // ❌ 编译错误:不能重写静态计算属性  
    // override static var name: String { return "Child" }
}
class - 可以重写

swift

复制代码
class Parent {
    class var version: String { return "1.0" }
    class var name: String { return "Parent" }
}

class Child: Parent {
    // ✅ 可以重写类属性
    override class var version: String { return "2.0" }
    override class var name: String { return "Child" }
}

2. 存储属性 vs 计算属性

static - 支持存储属性和计算属性

swift

复制代码
class MyClass {
    // ✅ 存储属性
    static let constant = "常量"
    static var variable = "变量"
    
    // ✅ 计算属性
    static var computedProperty: String {
        return "计算属性"
    }
}
class - 只支持计算属性

swift

复制代码
class MyClass {
    // ❌ 编译错误:class 不能用于存储属性
    // class let constant = "常量"
    // class var variable = "变量"
    
    // ✅ 只能用于计算属性
    class var computedProperty: String {
        return "类计算属性"
    }
}

实际使用示例

单例模式中的使用

swift

复制代码
class NetworkManager {
    // static 用于存储单例实例
    static let shared = NetworkManager()
    
    // class 用于提供类型信息(如果需要重写)
    class var baseURL: String {
        return "https://api.example.com"
    }
    
    private init() {}
}

class TestNetworkManager: NetworkManager {
    // ✅ 可以重写类属性
    override class var baseURL: String {
        return "https://test-api.example.com"
    }
    
    // ❌ 不能重写静态属性
    // override static let shared = TestNetworkManager()
}

配置信息示例

swift

复制代码
class AppConfig {
    // 静态存储属性 - 不会改变的基础配置
    static let appName = "MyApp"
    static let buildNumber = "1.0.0"
    
    // 类计算属性 - 可能被子类重写的配置
    class var apiBaseURL: String {
        return "https://production.api.com"
    }
    
    class var isDebugMode: Bool {
        #if DEBUG
        return true
        #else
        return false
        #endif
    }
}

class TestAppConfig: AppConfig {
    // ✅ 重写环境相关的配置
    override class var apiBaseURL: String {
        return "https://test.api.com"
    }
}

在结构体和枚举中的表现

static - 适用于所有类型

swift

复制代码
struct MathUtils {
    static let pi = 3.14159
    static var calculationCount = 0
}

enum NetworkError: String {
    static let defaultMessage = "网络错误"
    case timeout = "请求超时"
    case serverError = "服务器错误"
}

class - 仅适用于类

swift

复制代码
// ❌ 在结构体和枚举中不能使用 class
struct MathUtils {
    // class var test: String { return "test" } // 编译错误
}

enum NetworkError {
    // class var test: String { return "test" } // 编译错误
}

协议中的使用

static - 在协议中定义类型属性要求

swift

复制代码
protocol Configurable {
    static var configKey: String { get }
    static func setup()
}

class MyClass: Configurable {
    // 实现协议要求
    static var configKey: String = "MyClassConfig"
    
    static func setup() {
        print("初始化设置")
    }
}

内存和行为特性

两者共同点:

  • ✅ 都是类型属性,属于类型本身而不是实例

  • ✅ 在程序运行期间只有一份内存

  • ✅ 通过类型名访问:MyClass.staticProperty

  • ✅ 线程安全的懒加载

选择指南

使用 static 当:

swift

复制代码
// 1. 需要存储属性
static let databasePath = "/data/db"

// 2. 不需要子类重写
static let appVersion = "1.0.0"

// 3. 在结构体或枚举中
static let defaultSize = CGSize(width: 100, height: 100)

// 4. 单例模式
static let shared = MyManager()

使用 class 当:

swift

复制代码
// 1. 需要子类重写行为
class var shouldLog: Bool { 
    return true 
}

// 2. 基于类型提供不同值
class var supportedFileTypes: [String] { 
    return ["json", "xml"] 
}

// 3. 多态行为
class var maximumConnections: Int { 
    return 5 
}

总结对比表

特性 static class
存储属性 ✅ 支持 ❌ 不支持
计算属性 ✅ 支持 ✅ 支持
可重写性 ❌ 不可重写 ✅ 可重写
适用类型 类、结构体、枚举 仅类
内存特性 全局唯一 全局唯一
访问方式 Type.property Type.property

理解这个区别对于设计良好的 Swift 代码架构非常重要!

相关推荐
合作小小程序员小小店2 小时前
web网页开发,在线物流管理系统,基于Idea,html,css,jQuery,jsp,java,SSM,mysql
java·前端·后端·spring·intellij-idea·web
emiya_saber3 小时前
Linux 进程调度管理
linux·运维·服务器
yangzhi_emo3 小时前
配置dns主从服务
linux·运维·服务器
这周也會开心3 小时前
SpringMVC整理
java·springmvc
東雪木3 小时前
Spring Boot 2.x 集成 Knife4j (OpenAPI 3) 完整操作指南
java·spring boot·后端·swagger·knife4j·java异常处理
数学难3 小时前
Java面试题2:Java线程池原理
java·开发语言
Charles_go3 小时前
C#8、有哪些访问修饰符
java·前端·c#
qwer12321ck763 小时前
srcType instanceof Class 及泛型 vs 普通类
java
咸鱼求放生3 小时前
Java 8 Stream API
java·开发语言