面试题: 类方法声明时 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新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
ssshooter12 小时前
Tauri 踩坑 appLink 修改后闪退
前端·ios·rust
二流小码农16 小时前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos
开心就好20251 天前
UniApp开发应用多平台上架全流程:H5小程序iOS和Android
后端·ios
开心就好20251 天前
免 Xcode 的 iOS 开发新选择?聊聊一款更轻量的 iOS 开发 IDE kxapp 快蝎
后端·ios
恋猫de小郭2 天前
Apple 的 ANE 被挖掘,AI 硬件公开,宣传的 38 TOPS 居然是"数字游戏"?
前端·人工智能·ios
东坡肘子2 天前
OpenClaw 不错,但我好像没有那么需要 -- 肘子的 Swift 周报 #125
人工智能·swiftui·swift
忆江南2 天前
iOS 深度解析
flutter·ios
没有故事的Zhang同学2 天前
05-主题|事件响应者链@iOS-应用场景与进阶实践
ios
FeliksLv3 天前
尝试给Lookin 支持 MCP
ios
没有故事的Zhang同学3 天前
01-研究系统框架@Web@iOS | JavaScriptCore 框架:从使用到原理解析
ios