479

The following code compiles in Swift 1.2:

class myClass {
    static func myMethod1() {
    }
    class func myMethod2() {
    }
    static var myVar1 = ""
}

func doSomething() {
    myClass.myMethod1()
    myClass.myMethod2()
    myClass.myVar1 = "abc"
}

What is the difference between a static function and a class function? Which one should I use, and when?

If I try to define another variable class var myVar2 = "", it says:

Class stored properties not yet supported in classes; did you mean 'static'?

When this feature is supported, what will the difference be between a static variable and a class variable (i.e. when both are defined in a class)? Which one should I use, and when?

(Xcode 6.3)

Senseful
  • 86,719
  • 67
  • 308
  • 465
  • Similar question here: [static vs class as class variable/method (Swift)](http://stackoverflow.com/questions/29206465/static-vs-class-as-class-variable-method-swift). – Martin R Apr 14 '15 at 20:25
  • Static Can be applied on Stored Property as well as Computed Properties. Class can only be applied on computed properties. https://iosarchitect.com/static-and-class-keyword-in-swift/ – Keshu R. Sep 27 '21 at 15:12

8 Answers8

797

static and class both associate a method with a class, rather than an instance of a class. The difference is that subclasses can override class methods; they cannot override static methods.

class properties function in the same way (subclasses can override them).

mipadi
  • 398,885
  • 90
  • 523
  • 479
  • 102
    So what is the difference between `final class` function and 'static' function within a class? – hippo_san Jul 17 '15 at 15:11
  • 66
    @hippo_san, in a base class the two are functionally the same. However, `final` can be used to cut off further overrides when used in a subclass. The two both have their place, I would say the use of `static` or `final` when used on a class function is trivial and up to your style choice. – Andrew Robinson Jul 27 '15 at 20:36
  • 9
    ah, so `static func foo(){}` in Swift is like `public static final foo(){}` in Java? – Ky - Aug 06 '15 at 23:42
  • 3
    @Supuhstar: Basically, yes. – mipadi Aug 06 '15 at 23:43
  • 1
    If the two are the same, then actually we don't need "static"? – allenlinli Aug 11 '16 at 06:09
  • 1
    @allenlinli: They're not the same thing. – mipadi Aug 15 '16 at 16:36
  • 2
    @mipadi I understand now. For class functions, we can replace "static" with "final class", but for properties in a class, we can have only static properties instead of class properties. So the "static" keyword still has its place. – allenlinli Aug 16 '16 at 23:11
  • @hippo_san not the same. Number of Inheritance branches can be infinite. And maybe in some branch you prefer to close override and in some - not. – Mike Glukhov Feb 01 '17 at 12:44
  • 1
    @mipadi, more precisely, Swift (for now it is Swift3) does not support class stored properties, but one can define class computed properties in Swift. – yuchen Mar 16 '17 at 09:38
  • **Note** that `class` properties are allowed, but only within classes – Jakub Truhlář Jun 18 '17 at 08:05
  • "final func" is just a "normal" one but prevented to be overridden nor redeclared by subclasses. – NiravS Jul 22 '17 at 11:09
  • Hmmm. Curious why "subclasses can override class methods; they cannot override static methods," but in 4.2 you *can* use `static` methods in a protocol, but you *can not* use `class` methods. Seems to me everything in a protocol is overridden, so shouldn't it be the other way around? – Popmedic Jan 14 '19 at 13:45
  • Also I think we can achieve the same as a `static` method using a `final` class, note, not a `final class` method. But this is probably overkill – Pranav Kasetti Jan 24 '19 at 19:46
  • static functions can be overwritten as well, but you cannot call super – Peter Lapisu Aug 02 '19 at 09:00
  • 1
    If the protocol allows us to define class methods then value types can not conform to those protocols. @Popmedic. – guru Jul 28 '20 at 08:07
  • Static functions can not be overridden in swift. @Peter Lapisu. – guru Jul 28 '20 at 08:08
  • What does even "not possible in Swift yet"? It was already included in language but could not be used? TBH, the more I code in Swift the clearer it gets that Swift is result of very shitty planning and design – Farid Dec 19 '22 at 17:25
  • @Farid: At the time, the feature was planned but had not yet been implemented (the answer was written in the Swift 1 days). Class properties have since been added. – mipadi Jan 02 '23 at 06:22
85

I tried mipadi's answer and comments on playground. And thought of sharing it. Here you go. I think mipadi's answer should be mark as accepted.

class A{
    class func classFunction(){
    }
    static func staticFunction(){
    }
    class func classFunctionToBeMakeFinalInImmediateSubclass(){
    }
}

class B: A {
    override class func classFunction(){
        
    }
    
    //Compile Error. Class method overrides a 'final' class method
    override static func staticFunction(){
        
    }
    
    //Let's avoid the function called 'classFunctionToBeMakeFinalInImmediateSubclass' being overriden by subclasses
    
    /* First way of doing it
    override static func classFunctionToBeMakeFinalInImmediateSubclass(){
    }
    */
    
    // Second way of doing the same
    override final class func classFunctionToBeMakeFinalInImmediateSubclass(){
    }
    
    //To use static or final class is choice of style.
    //As mipadi suggests I would use. static at super class. and final class to cut off further overrides by a subclass
}

class C: B{
    //Compile Error. Class method overrides a 'final' class method
    override static func classFunctionToBeMakeFinalInImmediateSubclass(){
        
    }
}
Alex Zavatone
  • 4,106
  • 36
  • 54
MadNik
  • 7,713
  • 2
  • 37
  • 39
32

Regarding to OOP, the answer is too simple:

The subclasses can override class methods, but cannot override static methods.

In addition to your post, if you want to declare a class variable (like you did class var myVar2 = ""), you should do it as follow:

class var myVar2: String {
    return "whatever you want"
}
eMdOS
  • 1,693
  • 18
  • 23
29

Testing in Swift 4 shows performance difference in simulator. I made a class with "class func" and struct with "static func" and ran them in test.

static func is:

  • 20% faster without compiler optimization
  • 38% faster when optimization -whole-module-optimization is enabled.

However, running the same code on iPhone 7 under iOS 10.3 shows exactly the same performance.

Here is sample project in Swift 4 for Xcode 9 if you like to test yourself https://github.com/protyagov/StructVsClassPerformance

Alex Protyagov
  • 511
  • 6
  • 6
24

I got this confusion in one of my project as well and found this post, very helpful. Tried the same in my playground and here is the summary. Hope this helps someone with stored properties and functions of type static, final,class, overriding class vars etc.

class Simple {

    init() {print("init method called in base")}

    class func one() {print("class - one()")}

    class func two() {print("class - two()")}

    static func staticOne() {print("staticOne()")}

    static func staticTwo() {print("staticTwo()")}

    final func yesFinal() {print("yesFinal()")}

    static var myStaticVar = "static var in base"

    //Class stored properties not yet supported in classes; did you mean 'static'?
    class var myClassVar1 = "class var1"

    //This works fine
    class var myClassVar: String {
       return "class var in base"
    }
}

class SubSimple: Simple {
    //Successful override
    override class func one() {
        print("subClass - one()")
    }
    //Successful override
    override class func two () {
        print("subClass - two()")
    }

    //Error: Class method overrides a 'final' class method
    override static func staticOne() {

    }

    //error: Instance method overrides a 'final' instance method
    override final func yesFinal() {

    }

    //Works fine
    override class var myClassVar: String {
        return "class var in subclass"
    }
}

And here is the testing samples:

print(Simple.one())
print(Simple.two())
print(Simple.staticOne())
print(Simple.staticTwo())
print(Simple.yesFinal(Simple()))
print(SubSimple.one())
print(Simple.myStaticVar)
print(Simple.myClassVar)
print(SubSimple.myClassVar)

//Output
class - one()
class - two()
staticOne()
staticTwo()
init method called in base
(Function)
subClass - one()
static var in base
class var in base
class var in subclass
nburk
  • 22,409
  • 18
  • 87
  • 132
Santosh
  • 2,900
  • 1
  • 16
  • 16
12

Swift class vs static

[Reference vs Value Type]

class is used inside Reference Type(class, function):

  • computed property
  • method
  • can be overridden by subclass

static is used inside Reference Type(class, function) and Value Type(struct, enum, tuple):

  • computed property and stored property
  • method
  • cannot be changed by subclass
protocol MyProtocol {
//    class var protocolClassVariable : Int { get }//ERROR: Class properties are only allowed within classes
    static var protocolStaticVariable : Int { get }
    
//    class func protocolClassFunc()//ERROR: Class methods are only allowed within classes
    static func protocolStaticFunc()
}

struct ValueTypeStruct: MyProtocol {
    //MyProtocol implementation begin
    static var protocolStaticVariable: Int = 1
    
    static func protocolStaticFunc() {
        
    }
    //MyProtocol implementation end
    
//    class var classVariable = "classVariable"//ERROR: Class properties are only allowed within classes
    static var staticVariable = "staticVariable"

//    class func classFunc() {} //ERROR: Class methods are only allowed within classes
    static func staticFunc() {}
}

class ReferenceTypeClass: MyProtocol {
    //MyProtocol implementation begin
    static var protocolStaticVariable: Int = 2
    
    static func protocolStaticFunc() {
        
    }
    //MyProtocol implementation end
    
    var variable = "variable"

//    class var classStoredPropertyVariable = "classVariable"//ERROR: Class stored properties not supported in classes

    class var classComputedPropertyVariable: Int {
        get {
            return 1
        }
    }

    static var staticStoredPropertyVariable = "staticVariable"

    static var staticComputedPropertyVariable: Int {
        get {
            return 1
        }
    }

    class func classFunc() {}
    static func staticFunc() {}
}

final class FinalSubReferenceTypeClass: ReferenceTypeClass {
    override class var classComputedPropertyVariable: Int {
        get {
            return 2
        }
    }
    override class func classFunc() {}
}

//class SubFinalSubReferenceTypeClass: FinalSubReferenceTypeClass {}// ERROR: Inheritance from a final class

yoAlex5
  • 29,217
  • 8
  • 193
  • 205
9

There's one more difference: class can be used to define type properties of computed type only. If you need a stored type property use static instead.

You define type properties with the static keyword. For computed type properties for class types, you can use the class keyword instead to allow subclasses to override the superclass’s implementation.

https://docs.swift.org/swift-book/LanguageGuide/Properties.html

pkamb
  • 33,281
  • 23
  • 160
  • 191
Maciek Czarnik
  • 5,950
  • 2
  • 37
  • 50
  • man read carefully that article and compare with your "answer". You can use `static` for both computed and stored properties. The difference is `use the class keyword instead to allow subclasses to override the superclass’s implementation` – Vyachaslav Gerchicov Oct 08 '21 at 07:00
8

Adding to above answers static methods are static dispatch means the compiler know which method will be executed at runtime as the static method can not be overridden while the class method can be a dynamic dispatch as subclass can override these.

garg
  • 2,651
  • 1
  • 24
  • 21