Swift中的Static vs Class:如何为代码做出选择?

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:Swift中static与class的永恒之争

\n

如果你曾经用Swift编写过代码,那么你很可能遇到过这种情况:需要创建一个属于类型本身而非其实例的方法或变量。这时就会出现一个难题——应该使用关键字static还是class?在Stack Overflow上,这个问题已经积累了数千次浏览,这并非没有原因:两者之间的差异虽然微妙,但对于正确设计应用程序架构却至关重要。

\n

在本教程中,我们将一劳永逸地弄清楚Swift中static和class的区别、何时使用它们,以及如何在继承中避免陷阱。让我们开始吧!

\n\n

什么是类型属性和方法?

\n

在深入探讨之前,让我们先回顾一下基础知识。在Swift中,每个类、结构体或枚举都有两种成员:

\n
    \n
  • 实例成员(Instance)——属于特定对象。要使用它们,需要创建一个实例:let obj = MyClass()。
  • \n
  • 类型成员(Type)——属于类型本身。通过类型名称调用:MyClass.someMethod()。
  • \n
\n

在Swift中,创建类型属性和方法时使用关键字static和class。而有趣的部分就从这里开始。

\n\n

Static:严格且不可变

\n

关键字static是您可靠的朋友,当您想要创建一个不能在子类中重写的属性或方法时。它对于类、结构体和枚举的工作方式相同。

\n

让我们看一个例子。假设我们正在编写一个学生管理应用,并希望存储已创建对象的总数:

\n\n
class Student {\n    static var totalCount = 0\n    \n    let name: String\n    \n    init(name: String) {\n        self.name = name\n        Student.totalCount += 1\n    }\n    \n    static func printTotal() {\n        print("学生总数:\\(totalCount)")\n    }\n}\n\nlet s1 = Student(name: "伊万")\nlet s2 = Student(name: "玛丽亚")\nStudent.printTotal() // 输出:学生总数:2
\n\n

请注意:我们通过类名Student来访问totalCount和printTotal(),而不是通过实例。这对于计数器、默认配置或数据缓存非常方便。

\n\n

结构体和枚举中的Static

\n

在结构体和枚举中,static是声明类型成员的唯一方式。例如:

\n\n
enum HTTPMethod {\n    case get\n    case post\n    case put\n    \n    static let defaultMethod: HTTPMethod = .get\n}\n\nstruct AppConfig {\n    static let apiURL = "https://api.example.com"\n    static let timeout: Double = 30.0\n}
\n\n

在这里,static完美地工作,因为结构体和枚举不支持继承,因此也不需要重写。

\n\n

Class:继承的灵活性

\n

而关键字class则是为那些使用类(且仅限类)并希望允许子类重写方法或属性的开发者准备的工具。class不能在结构体或枚举中使用。

\n

假设我们有一个基类Vehicle,我们希望每个子类都能提供自己的描述版本:

\n\n
class Vehicle {\n    class func description() -> String {\n        return "这是一种交通工具"\n    }\n}\n\nclass Car: Vehicle {\n    override class func description() -> String {\n        return "这是一辆汽车"\n    }\n}\n\nclass Bicycle: Vehicle {\n    override class func description() -> String {\n        return "这是一辆自行车"\n    }\n}\n\nprint(Vehicle.description()) // 这是一种交通工具\nprint(Car.description())     // 这是一辆汽车\nprint(Bicycle.description()) // 这是一辆自行车                

博客

书籍推荐