What is the difference between static func and cla

2020-01-24 18:37发布

I can see these definitions in the Swift library:

extension Bool : BooleanLiteralConvertible {
    static func convertFromBooleanLiteral(value: Bool) -> Bool
}

protocol BooleanLiteralConvertible {
    typealias BooleanLiteralType
    class func convertFromBooleanLiteral(value: BooleanLiteralType) -> Self
}

What's the difference between a member function defined as static func and another one defined as class func? Is it simply that static is for static functions of structs and enums, and class for classes and protocols? Are there any other differences that one should know about? What is the rationale for having this distinction in the syntax itself?

8条回答
迷人小祖宗
2楼-- · 2020-01-24 19:21

This example will clear every aspect!

import UIKit

class Parent {
    final func finalFunc() -> String { // Final Function, cannot be redeclared.
        return "Parent Final Function."
    }

    static func staticFunc() -> String { // Static Function, can be redeclared.
        return "Parent Static Function."
    }

    func staticFunc() -> String { // Above function redeclared as Normal function.
        return "Parent Static Function, redeclared with same name but as non-static(normal) function."
    }

    class func classFunc() -> String { // Class Function, can be redeclared.
        return "Parent Class Function."
    }

    func classFunc() -> String { // Above function redeclared as Normal function.
        return "Parent Class Function, redeclared with same name but as non-class(normal) function."
    }

    func normalFunc() -> String { // Normal function, obviously cannot be redeclared.
        return "Parent Normal Function."
    }
}

class Child:Parent {

    // Final functions cannot be overridden.

    override func staticFunc() -> String { // This override form is of the redeclared version i.e: "func staticFunc()" so just like any other function of normal type, it can be overridden.
        return "Child Static Function redeclared and overridden, can simply be called Child Normal Function."
    }

    override class func classFunc() -> String { // Class function, can be overidden.
        return "Child Class Function."
    }

    override func classFunc() -> String { // This override form is of the redeclared version i.e: "func classFunc()" so just like any other function of normal type, it can be overridden.
        return "Child Class Function, redeclared and overridden, can simply be called Child Normal Function."
    }

    override func normalFunc() -> String { // Normal function, can be overridden.
        return "Child Normal Function."
    }
}

let parent = Parent()
let child = Child()

// Final
print("1. " + parent.finalFunc())   // 1. Can be called by object.
print("2. " + child.finalFunc())    // 2. Can be called by object, parent(final) function will be called.
// Parent.finalFunc()               // Cannot be called by class name directly.
// Child.finalFunc()                // Cannot be called by class name directly.

// Static
print("3. " + parent.staticFunc())  // 3. Cannot be called by object, this is redeclared version (i.e: a normal function).
print("4. " + child.staticFunc())   // 4. Cannot be called by object, this is override form redeclared version (normal function).
print("5. " + Parent.staticFunc())  // 5. Can be called by class name directly.
print("6. " + Child.staticFunc())   // 6. Can be called by class name direcly, parent(static) function will be called.

// Class
print("7. " + parent.classFunc())   // 7. Cannot be called by object, this is redeclared version (i.e: a normal function).
print("8. " + child.classFunc())    // 8. Cannot be called by object, this is override form redeclared version (normal function).
print("9. " + Parent.classFunc())   // 9. Can be called by class name directly.
print("10. " + Child.classFunc())   // 10. Can be called by class name direcly, child(class) function will be called.

// Normal
print("11. " + parent.normalFunc())  // 11. Can be called by object.
print("12. " + child.normalFunc())   // 12. Can be called by object, child(normal) function will be called.
// Parent.normalFunc()               // Cannot be called by class name directly.
// Child.normalFunc()                // Cannot be called by class name directly.

/*
 Notes:
 ___________________________________________________________________________
 |Types------Redeclare------Override------Call by object------Call by Class|
 |Final----------0--------------0---------------1------------------0-------|
 |Static---------1--------------0---------------0------------------1-------|
 |Class----------1--------------1---------------0------------------1-------|
 |Normal---------0--------------1---------------1------------------0-------|
 ---------------------------------------------------------------------------

 Final vs Normal function: Both are same but normal methods can be overridden.
 Static vs Class function: Both are same but class methods can be overridden.
 */

Output: Output all types of function

查看更多
Fickle 薄情
3楼-- · 2020-01-24 19:22

To be clearer, I make an example here,

class ClassA {
  class func func1() -> String {
    return "func1"
  }

  static func func2() -> String {
    return "func2"
  }

  /* same as above
  final class func func2() -> String {
    return "func2"
  }
  */
}

static func is same as final class func

Because it is final, we can not override it in subclass as below:

class ClassB : ClassA {
  override class func func1() -> String {
    return "func1 in ClassB"
  }

  // ERROR: Class method overrides a 'final` class method
  override static func func2() -> String {
    return "func2 in ClassB"
  }
}
查看更多
登录 后发表回答