编程移动开发者

在Swift中,static和class方法是什么?它们有什么区别,在哪里使用static,在哪里使用class,以及在使用它们时可能出现哪些错误?

用 Hintsage AI 助手通过面试

答案。

在C语言家族(包括Objective-C)的编程语言中,一直存在“类方法”(class methods)。在Swift中出现了两种类型的这种方法——static和class。它们允许在类型上调用方法,而不是在实例上。static用于结构体、枚举和绝对无法被重写的类,而class用于可以在子类中重写的类。

问题: 在可能继承的类层次结构中,static和class之间的混淆会出现,因为希望允许或禁止对子代的方法/属性进行重写。

解决方案:

  • static func — 允许定义一个与类型相关的函数(或属性),不能被重写(final)。
  • class func — 可以在子类中重写。

示例代码:

class Animal { class func makeSound() { print("某种通用动物声音") } static func kingdom() -> String { "Animalia" } } class Dog: Animal { override class func makeSound() { print("汪汪!") } // override static func kingdom() — 错误:static不能被重写! } Animal.makeSound() // 某种通用动物声音 Dog.makeSound() // 汪汪! print(Animal.kingdom()) // Animalia

关键特性:

  • static禁止重写,class允许重写。
  • static适合用于struct、enum和不可变类上的工具方法。
  • class仅用于类以支持重写。

带陷阱的问题。

可以在struct或enum中使用class func吗?

不可以,class func仅允许用于类。Struct和enum仅支持static方法和属性。

static属性可以是计算得出的和/或可变的(var)吗?

可以,static属性可以是计算属性(computed)和存储属性(stored),并通过static var定义。对于struct和enum,这是唯一一种通过类型本身而非实例使属性可用的方法。

示例代码:

struct Counter { static var totalCount = 0 static var nextId: Int { totalCount += 1 return totalCount } }

可以通过类的实例调用class方法吗?

可以,但不推荐:class方法始终与类型相关,而不是具体对象,因此将调用原始类型或重写的行为,而不涉及特定对象。

常见错误和反模式

  • 尝试在类的子类中重写static方法将导致编译错误。
  • 在不打算重写的地方使用class func(例如用于数学工具)。
  • 将class func应用于struct/enum — 编译错误。

生活中的例子

负面案例

对于静态工具类使用class func,尽管不打算重写。

优点:

  • 在后续更改需求时,签名具有灵活性。

缺点:

  • 可能导致后代中的不可控重写,从而导致应用程序的错误行为。

正面案例

对于常量和工具使用static,class用于可以在子类中实际更改的工厂方法。

优点:

  • 清晰区分继承合同和允许的操作。
  • 对于static方法具有优化的性能。

缺点:

  • 在大型层次结构中,很难追踪在哪里使用了static,哪里使用了class,这在设计API时需要细致考虑。