• Swift中声明类方法时用class 和 static 有什么区别?
  • 发布于 2个月前
  • 250 热度
    0 评论
  • Scys
  • 5 粉丝 39 篇博客
  •   
前言
在 Swift 中,最常用的类型包括类(Class)、结构体(Struct)和枚举(Enum)。在声明类方法时,既可以用 static 又可以用 class。在本篇文章中,我们将深入讨论 class 和 static 的区别,并通过实例代码来揭示他们的特性和使用方法。

class 和 static 在类中的使用
首先,让我们了解一下 class 和 static 这两个关键字。class 关键字用于定义类方法,这些方法只能由类本身调用,不能被类的实例调用。class 定义的类方法可以被子类覆盖。而 static 关键字用于定义静态方法,同样,这些方法只能由类本身调用,不能被类的实例调用。static 定义的静态方法不能被子类覆盖。

下面,我们通过一些代码示例来看看这两个关键字在实际使用中的区别。
class MyClass {
    class func classMethod() {
        print("classMethod in MyClass")
    }
    
    static func staticMethod() {
        print("staticMethod in MyClass")
    }
}

class MySubClass: MyClass {
    override class func classMethod() {
        print("classMethod in MySubClass")
    }
    // 堆代码 duidaima.com
    // 这里会报错,因为静态方法不能被覆盖
    // override static func staticMethod() { }
}
在上面的代码中,MyClass 定义了两个方法:classMethod 和 staticMethod。classMethod 使用 class 关键字定义,staticMethod 使用 static 关键字定义。然后,我们创建了一个 MyClass 的子类 MySubClass,在这个子类中,我们试图覆盖这两个方法。结果发现,classMethod 可以被 MySubClass 成功覆盖,而 staticMethod 无法被覆盖,因为 static 定义的方法不能被子类覆盖。

下面,我们来看看这两个方法如何被调用。
MyClass.classMethod() // 输出 "classMethod in MyClass"
MyClass.staticMethod() // 输出 "staticMethod in MyClass"

MySubClass.classMethod() // 输出 "classMethod in MySubClass"
MySubClass.staticMethod() // 输出 "staticMethod in MyClass"
可以看到,classMethod 和 staticMethod 都可以通过类名来调用。因为 MySubClass 覆盖了 classMethod,所以 MySubClass.classMethod() 调用的是 MySubClass 中的 classMethod。而 MySubClass.staticMethod() 调用的仍然是 MyClass 中的 staticMethod,因为 staticMethod 不能被覆盖。

在结构体和枚举中的使用
在 Objective-C 中,只能为类定义类型方法。在 Swift 中,您可以为所有类、结构和枚举定义类型方法。不同的是,在结构体(struct)和枚举(enum)这两种类型中,class 关键字是无法使用的,只能使用 static 关键字来定义类型方法。

当 static 关键字用于 struct 或 enum 中时,它的作用与在 class 中一样,定义的方法是属于类型本身的,可以直接通过类型名来调用,而无需创建该类型的实例。其实,struct 和 enum 本质上都是值类型,它们的方法默认就是不能被子类或者子类型覆盖的(不能继承),所以这里 static 关键字只有一个作用,就是定义类型方法。
struct MyStruct {
    static func staticMethod() {
        print("staticMethod in MyStruct")
    }
}

enum MyEnum {
    static func staticMethod() {
        print("staticMethod in MyEnum")
    }
}
MyStruct.staticMethod() // 输出 "staticMethod in MyStruct"
MyEnum.staticMethod() // 输出 "staticMethod in MyEnum"
在上面的代码中,我们定义了一个结构体 MyStruct 和一个枚举 MyEnum,并在这两个类型中都定义了一个静态方法 staticMethod。然后,我们可以通过类型名来调用这些静态方法。

为什么这么设计
class 和 static 在 Swift 中的设计,主要是为了提供两种不同的类方法。从设计角度来看,这两种关键字的区别主要在于它们的继承行为,即 class 定义的方法可以被子类覆盖,而 static 定义的方法不能被子类覆盖。这样的设计可以提供更大的灵活性,让开发者能够根据需要选择合适的方法类型。

从原理和底层实现来看,class 和 static 的区别主要体现在它们的方法调用机制上。class 定义的类方法是通过动态派发的方式来调用的,也就是说,当你调用一个类方法时,Swift 会在运行时查找并调用正确的方法。而 static 定义的静态方法是通过静态派发的方式来调用的,也就是说,当你调用一个静态方法时,Swift 会在编译时就确定这个方法的调用。
用户评论