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

相关推荐
初级代码游戏1 小时前
iOS开发 Swift 速记2:三种集合类型 Array Set Dictionary
开发语言·ios·swift
AIsoft_86889 小时前
iPhone录音重点标记:会议录音与重点内容同步保存功能实测
ios·iphone
00后程序员张9 小时前
使用Instruments工具深入分析iOS应用性能与启动时间优化
android·macos·ios·小程序·uni-app·cocoa·iphone
90后的晨仔12 小时前
Xcode 26.6编译 AFNetworking 报错全解:5 种方案从应急到根治
ios
初级代码游戏1 天前
iOS开发 Swift 速记1:变量和基本数据类型
开发语言·ios·swift
清水迎朝阳1 天前
客户端软件 — 用户统计方案
服务器·c++·客户端·用户统计
for_ever_love__1 天前
iOS:网络请求再学习
网络·学习·ios·objective-c
大龄秃头程序员1 天前
Swift 值类型真的每次都会拷贝吗?OC 老兵聊聊 COW
swift
2501_915921431 天前
SwiftUI开发框架入门指南:从基础到实战
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
2501_916007471 天前
Python实现HTTPS爬虫的完整指南:使用requests、BeautifulSoup、Selenium和Scrapy
爬虫·python·ios·小程序·https·uni-app·iphone