Reputation: 91641
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)
Upvotes: 489
Views: 200179
Reputation: 61
Here are few difference
Static ->
1- Type-Specific: Belong to the type itself, not to any instance.
2- Non-Overridable: Static properties and methods cannot be overridden by subclasses.
3- Memory Allocation: Only one copy exists for the entire type, shared among all instances.
4- Usage: Used to define constants, utility methods, and properties that should remain consistent and unchanged across all instances of the type.
5- in static we can use computed properties and as well as stored property.
1- Type-Specific: Belong to the type itself, not to any instance.
2- Overridable: Class properties (must be computed) and methods can be overridden by subclasses.
3- Memory Allocation: Only one copy exists for the entire type, shared among all instances.
4 Usage: Used to define properties and methods that may need to be customized or extended in subclasses.
5- in class we can only use computed properties
Upvotes: 0
Reputation: 410542
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).
Upvotes: 818
Reputation: 34175
Swift class vs static
class
is used inside Reference Type
(class, function):
static
is used inside Reference Type
(class, function) and Value Type
(struct, enum, tuple):
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
Upvotes: 14
Reputation: 6181
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
Upvotes: 9
Reputation: 7793
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(){
}
}
Upvotes: 87
Reputation: 2727
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.
Upvotes: 8
Reputation: 1713
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"
}
Upvotes: 32
Reputation: 521
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:
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
Upvotes: 30
Reputation: 2914
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
Upvotes: 24