面试题: 类方法声明时 class 和 static 的区别

这里每天分享一个 iOS 的新知识,快来关注我吧

前言

在 Swift 中,最常用的类型包括类(Class)、结构体(Struct)和枚举(Enum)。在声明类方法时,既可以用 static 又可以用 class。在本篇文章中,我们将深入讨论 classstatic 的区别,并通过实例代码来揭示他们的特性和使用方法。

class 和 static 在类中的使用

首先,让我们了解一下 classstatic 这两个关键字。

class 关键字用于定义类方法,这些方法只能由类本身调用,不能被类的实例调用class 定义的类方法可以被子类覆盖。

static 关键字用于定义静态方法,同样,这些方法只能由类本身调用,不能被类的实例调用static 定义的静态方法不能被子类覆盖。

下面,我们通过一些代码示例来看看这两个关键字在实际使用中的区别。

typescript 复制代码
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")
    }
    
    // 这里会报错,因为静态方法不能被覆盖
    // override static func staticMethod() { }
}

在上面的代码中,MyClass 定义了两个方法:classMethodstaticMethodclassMethod 使用 class 关键字定义,staticMethod 使用 static 关键字定义。然后,我们创建了一个 MyClass 的子类 MySubClass,在这个子类中,我们试图覆盖这两个方法。

结果发现,classMethod 可以被 MySubClass 成功覆盖,而 staticMethod 无法被覆盖,因为 static 定义的方法不能被子类覆盖。

下面,我们来看看这两个方法如何被调用。

scss 复制代码
MyClass.classMethod() // 输出 "classMethod in MyClass"
MyClass.staticMethod() // 输出 "staticMethod in MyClass"

MySubClass.classMethod() // 输出 "classMethod in MySubClass"
MySubClass.staticMethod() // 输出 "staticMethod in MyClass"

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

在结构体和枚举中的使用

在 Objective-C 中,只能为类定义类型方法。在 Swift 中,您可以为所有类、结构和枚举定义类型方法。

不同的是,在结构体(struct)和枚举(enum)这两种类型中,class 关键字是无法使用的,只能使用 static 关键字来定义类型方法。

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

swift 复制代码
struct MyStruct {
    static func staticMethod() {
        print("staticMethod in MyStruct")
    }
}

enum MyEnum {
    static func staticMethod() {
        print("staticMethod in MyEnum")
    }
}
scss 复制代码
MyStruct.staticMethod() // 输出 "staticMethod in MyStruct"
MyEnum.staticMethod() // 输出 "staticMethod in MyEnum"

在上面的代码中,我们定义了一个结构体 MyStruct 和一个枚举 MyEnum,并在这两个类型中都定义了一个静态方法 staticMethod。然后,我们可以通过类型名来调用这些静态方法。

为什么这么设计

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

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

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 "iOS新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
安和昂6 小时前
【iOS】Blocks
macos·ios·cocoa
OKXLIN1 天前
IOS UITextField 无法隐藏键盘问题
ios·objective-c
AL.千灯学长1 天前
DeepSeek接入Siri(已升级支持苹果手表)完整版硅基流动DeepSeek-R1部署
人工智能·gpt·ios·ai·苹果vision pro
openinstall全渠道统计2 天前
免填邀请码工具:赋能六大核心场景,重构App增长新模型
android·ios·harmonyos
早起的年轻人2 天前
Flutter CupertinoNavigationBar iOS 风格导航栏的组件
flutter·ios
貂蝉空大2 天前
uni-app开发安卓和ios app 真机调试
android·ios·uni-app
胖虎12 天前
iOS 中的圆角与平滑圆角:从新特性到老项目适配
ios·圆角·平滑圆角·cornercurve
志飞2 天前
ios UICollectionView使用自定义UICollectionViewCell
ios·collectionview·自定义cell
Neo Evolution3 天前
Flutter与移动开发的未来:谷歌的技术愿景与实现路径
android·人工智能·学习·ios·前端框架·webview·着色器
没头脑的ht3 天前
ios App的启动过程和启动优化
ios