首先swift中的static同样具有类属性和类方法的特性,这点和很多语言类似,在Swift中,static关键字用于定义类型方法或类型属性,这些方法或属性属于类型本身,而不是类型的实例。这意味着你可以在不创建类型实例的情况下访问它们。
逐条分析解释下面的结论
1、static可以用于class, struct, 和 enum,而class只能用于类中的属性和方法。
Swift
//static用于struct
struct MyStruct {
static let myStaticConstant = 42
static func myStaticFunction() {
print("This is a static function.")
}
}
// 调用
let value = MyStruct.myStaticConstant
MyStruct.myStaticFunction()
Swift
// 使用 `static`(但更推荐使用 `class`,因为用class可以实现被继承)
class MyClass {
static var myClassVariable = 0
static func myClassFunction() {
print("This is a class function.")
}
}
//class用于修饰类中
class MyClass {
class var myClassVariable = 0
class func myClassFunction() {
print("This is a class function.")
}
}
// 调用
let value = MyClass.myClassVariable
MyClass.myClassFunction()
2、static定义的成员不能被重写,而class定义的成员可以被子类重写。
class关键字允许子类重写类型方法,而static关键字则不允许
Swift
class MyOtherClass {
// 使用class关键字,允许子类重写
class func myClassMethod() {
print("Parent class method.")
}
// 使用static关键字,不允许子类重写
static func myStaticMethod() {
print("This will not be overridden in subclasses.")
}
}
// 子类可以重写使用class关键字定义的方法
class SubClass: MyOtherClass {
override class func myClassMethod() {
print("Subclass method.")
}
}
3、static或者class修饰的类成员对所有实例共享(class有特殊性,后面讲解)
Swift
class Counter {
//l类变量,被类实例对象所共享有
static var sharedCount: Int = 0
// 实例变量,每个实例可以有不同的值
var instanceCount: Int
init() {
self.instanceCount = Counter.sharedCount
// 每当创建一个新的Counter实例时,sharedCount增加1
Counter.sharedCount += 1
}
}
// 创建第一个Counter实例
//输出instanceCount为 0
//输出sharedCount为 1
let counter1 = Counter()
// 创建第二个Counter实例
//输出instanceCount为 1
//输出sharedCount为 2
let counter2 = Counter()
这个例子展示了static成员是如何被所有实例共享的。无论创建多少个Counter实例,sharedCount始终只有一个副本。
其实swif中的这个类属性和实例对象属性类似上一篇文章提到的python中的类属性和对象属性。大家可结合上一篇《python中类变量、实例变量、@staticmethod、@classmethod详解(仿static关键字用法)》
一起理解。
-
实例对象属性没有初始化时就会指向类属性,这个时候类属性改变会影响实例对象属性;
-
实例对象属性申明并初始化过和类属性同名的属性时,那么实例对象属性就不指向类属性,这个时候彼此改变不相互影响
上面提到的class有特殊性,原因是class方法属性可以被子类重写,在父类中被class定义的方法或者属性可以在子类中重写
Swift
class MyClass {
static var sharedCount: Int = 0
class var classSharedCount: Int = 0
}
let instance1 = MyClass()
let instance2 = MyClass()
MyClass.sharedCount += 1
MyClass.classSharedCount += 1
print(instance1.sharedCount) // 输出1,这是通过类名访问的
print(instance1.classSharedCount) // 输出1,同上
// 创建子类
class MySubClass: MyClass {
override class var classSharedCount: Int {
return super.classSharedCount + 1
}
}
let subInstance = MySubClass()
print(subInstance.classSharedCount) // 输出2,因为子类重写了classSharedCount