442 Stimmen

Was ist der Unterschied zwischen static func und class func in Swift?

Ich kann diese Definitionen in der Swift-Bibliothek sehen:

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

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

Was ist der Unterschied zwischen einer Member-Funktion, die als static func definiert ist, und einer anderen, die als class func definiert ist? Ist es einfach so, dass static für statische Funktionen von Strukturen und Enums steht, und class für Klassen und Protokolle? Gibt es andere Unterschiede, die man kennen sollte? Was ist der Grund für diese Unterscheidung in der Syntax selbst?

24voto

Rehan Ali Khan Punkte 498

Dieses Beispiel wird jeden Aspekt löschen!

import UIKit

class Parent {
    final func finalFunc() -> String { // Endgültige Funktion, kann nicht neu deklariert werden.
        return "Elternendgültige Funktion."
    }

    static func staticFunc() -> String { // Statische Funktion, kann neu deklariert werden.
        return "Eltern-Statikfunktion."
    }

    func staticFunc() -> String { // Obengenannte Funktion neu deklariert als normale Funktion.
        return "Eltern-Statikfunktion, neu deklariert mit gleichem Namen, aber als nicht-statik (normale) Funktion."
    }

    class func classFunc() -> String { // Klassenfunktion, kann neu deklariert werden.
        return "Eltern-Klassenfunktion."
    }

    func classFunc() -> String { // Obengenannte Funktion neu deklariert als normale Funktion.
        return "Eltern-Klassenfunktion, neu deklariert mit gleichem Namen, aber als nicht-Klassen (normale) Funktion."
    }

    func normalFunc() -> String { // Normale Funktion, kann offensichtlich nicht neu deklariert werden.
        return "Elternnormale Funktion."
    }
}

class Child:Parent {

    // Endgültige Funktionen können nicht überschrieben werden.

    override func staticFunc() -> String { // Diese Überschreibung ist von der neu deklarierten Version, d.h. "func staticFunc()", also kann sie wie jede andere Funktion normalen Typs überschrieben werden.
        return "Kind-Statikfunktion neu deklariert und überschrieben, kann einfach Kind- normale Funktion genannt werden."
    }

    override class func classFunc() -> String { // Klassenfunktion, kann überschrieben werden.
        return "Kind-Klassenfunktion."
    }

    override func classFunc() -> String { // Diese Überschreibung ist von der neu deklarierten Version, d.h. "func classFunc()", also kann sie wie jede andere Funktion normalen Typs überschrieben werden.
        return "Kind-Klassenfunktion neu deklariert und überschrieben, kann einfach Kind- normale Funktion genannt werden."
    }

    override func normalFunc() -> String { // Normale Funktion, kann überschrieben werden.
        return "Kind-normale Funktion."
    }
}

let eltern = Parent()
let kind = Child()

// Endgültig
print("1. " + eltern.finalFunc())   // 1. Kann vom Objekt aus aufgerufen werden.
print("2. " + kind.finalFunc())    // 2. Kann vom Objekt aus aufgerufen werden, Eltern(endgültige) Funktion wird aufgerufen.
// Parent.finalFunc()               // Kann nicht direkt über den Klassennamen aufgerufen werden.
// Child.finalFunc()                // Kann nicht direkt über den Klassennamen aufgerufen werden.

// Statisch
print("3. " + eltern.staticFunc())  // 3. Kann vom Objekt aus nicht aufgerufen werden, dies ist die neu deklarierte Version (d.h. eine normale Funktion).
print("4. " + kind.staticFunc())   // 4. Kann vom Objekt aus nicht aufgerufen werden, dies ist die Überschreibungsform der neu deklarierten Version (normale Funktion).
print("5. " + Parent.staticFunc())  // 5. Kann direkt über den Klassennamen aufgerufen werden.
print("6. " + Child.staticFunc())   // 6. Kann direkt über den Klassennamen aufgerufen werden, Eltern(statische) Funktion wird aufgerufen.

// Klasse
print("7. " + eltern.classFunc())   // 7. Kann vom Objekt aus nicht aufgerufen werden, dies ist die neu deklarierte Version (d.h. eine normale Funktion).
print("8. " + kind.classFunc())    // 8. Kann vom Objekt aus nicht aufgerufen werden, dies ist die Überschreibungsform der neu deklarierten Version (normale Funktion).
print("9. " + Parent.classFunc())   // 9. Kann direkt über den Klassennamen aufgerufen werden.
print("10. " + Child.classFunc())   // 10. Kann direkt über den Klassennamen aufgerufen werden, Kind(Klassen) Funktion wird aufgerufen.

// Normal
print("11. " + eltern.normalFunc())  // 11. Kann vom Objekt aus aufgerufen werden.
print("12. " + kind.normalFunc())   // 12. Kann vom Objekt aus aufgerufen werden, Kind(normale) Funktion wird aufgerufen.
// Parent.normalFunc()               // Kann nicht direkt über den Klassennamen aufgerufen werden.
// Child.normalFunc()                // Kann nicht direkt über den Klassennamen aufgerufen werden.

/*
 Notizen:
 ___________________________________________________________________________
 |Typen------Neudeklarieren------Überschreiben------Aufruf vom Objekt------Aufruf der Klasse|
 |Endgültig----------0--------------0---------------1------------------0-------|
 |Statisch---------1--------------0---------------0------------------1-------|
 |Klasse----------1--------------1---------------0------------------1-------|
 |Normal---------0--------------1---------------1------------------0-------|
 ---------------------------------------------------------------------------

 Endgültig vs. Normale Funktion: Beide sind gleich, aber normale Methoden können überschrieben werden.
 Statisch vs. Klassenfunktion: Beide sind gleich, aber Klassenmethoden können überschrieben werden.
 */

Output: Output all types of function

15voto

Milad Punkte 1239

Laut dem von Apple veröffentlichten Swift 2.2 Buch:

„Sie geben Typenmethoden an, indem Sie das static Schlüsselwort vor dem func Schlüsselwort der Methode schreiben. Klassen können auch das class Schlüsselwort verwenden , um Unterklassen zu ermöglichen, die Implementierung der Superklasse dieser Methode zu überschreiben.“

10voto

LiangWang Punkte 6894

Von Swift2.0 sagt Apple:

"Präfixieren Sie immer Typ-Eigenschaftsanforderungen mit dem Schlüsselwort static, wenn Sie sie in einem Protokoll definieren. Diese Regel gilt auch dann, wenn Typ-Eigenschaftsanforderungen mit dem Schlüsselwort class oder static versehen werden können, wenn sie von einer Klasse implementiert werden:"

-7voto

Kumar Utsav Punkte 11

Dies wird als Typmethoden bezeichnet und mit Punkt-Syntax aufgerufen, wie Instanzmethoden. Sie rufen jedoch Typmethoden auf dem Typ auf, nicht auf einer Instanz dieses Typs. So rufen Sie eine Typmethode auf einer Klasse namens SomeClass auf:

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X