2015-04-14 11 views
271

Poniższy kod kompiluje w Swift 1.2:Statyczne vs funkcje/zmienne klas w klasach Swift?

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

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

Jaka jest różnica między statycznej funkcji i klasy funkcji? Którego powinienem użyć i kiedy?

Gdy próbuję zdefiniować innej zmiennej class var myVar2 = "", to mówi:

Class przechowywane właściwości jeszcze nie jest obsługiwana w klasach; miałeś na myśli "statyczny"?

Kiedy ta funkcja jest obsługiwana, jaka będzie różnica między być statycznym zmiennej i klasy zmiennej (czyli gdy oba są zdefiniowane w klasie)? Którego powinienem użyć i kiedy?

(Xcode 6,3)

+0

Podobne pytanie tutaj: [statyczny vs klasy jako zmienną klasy/metody (Swift)] (http://stackoverflow.com/questions/29206465/static-vs-class-as-class-variable-method-swift). –

Odpowiedz

434

static i class zarówno powiązania metodę z klasy niż instancje klasy. Różnica polega na tym, że podklasy mogą przesłonić metody class; nie mogą przesłonić metod static.

class właściwości będą teoretycznie funkcjonować w ten sam sposób (podklasy mogą je zastępować), ale nie są jeszcze możliwe w Swift.

+48

Jaka jest więc różnica pomiędzy funkcją "ostatniej klasy" a "statyczną" funkcją w klasie? –

+28

@hippo_san, w klasie bazowej te dwa są funkcjonalnie takie same. Jednakże, 'final' może być użyty do odcięcia dalszych przesłonięć, gdy jest używany w podklasie. Obaj mają swoje miejsce, powiedziałbym, że użycie 'static' lub' final' przy użyciu funkcji klasy jest trywialne i do wyboru twojego stylu. –

+7

ah, więc 'static func foo() {}' w Swift jest jak 'public static final foo() {}' w Javie? – Supuhstar

20

odniesieniu do OOP, odpowiedź jest zbyt prosta:

podklas może przesłonić klasy metod, ale nie może zastąpić statycznych metod.

Oprócz postu, jeśli chcesz zadeklarować zmienną klasy (jak to zrobiłeś class var myVar2 = ""), należy to zrobić następująco:

class var myVar2:String { 
    return "whatever you want" 
} 
44

Próbowałem mipadi za odpowiedzi i komentarzy na placu zabaw. I myśl o dzieleniu się nim. Proszę bardzo. Myślę, że odpowiedź mipadi powinna być oceniona jako zaakceptowana.

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(){ 

    } 

    //Lets 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(){ 

    } 
} 
17

Dostałem to zamieszanie w jednym z moich projektów i znalazłem ten post, bardzo pomocny. Wypróbowałem to samo na moim placu zabaw i tutaj jest podsumowanie. Nadzieję, że to pomoże ktoś z zapisanymi właściwościami i funkcjami typu static, final, class, przesłanianie klasy vars itp

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" 
    } 
} 

A oto próbki testowe:

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 
9

Testowanie w Swift 4 pokazuje różnicę wydajności w symulatorze. Zrobiłem zajęcia z "class func" i struct z "static func" i przetestowałem je.

statyczne func jest:

  • 20% szybciej bez optymalizacji kompilatora
  • 38% szybciej optymalizacji -Całe moduł optymalizacji jest włączony.

Jednak ten sam kod na iPhone 7 pod iOS 10.3 pokazuje dokładnie taką samą wydajność.

Oto przykładowy projekt w Swift 4 dla Xcode 9 jeśli chcesz przetestować sobie https://github.com/protyagov/StructVsClassPerformance

2

zarówno static i class słów kluczowych pozwala nam dołączyć zmiennych do klasy zamiast do instancji klasy. Na przykład możesz utworzyć klasę Student z takimi właściwościami, jak name i age, a następnie utworzyć nieruchomą właściwość , która jest własnością samej klasy Student, a nie pojedynczych instancji.

Gdzie static iróżnią się sposobem obsługi dziedziczenia: Po utworzeniu właściwości statycznej staje się ona własnością klasy i nie może być zmieniona przez podklasy, natomiast w przypadku użycia klasy może zostać zastąpiona w razie potrzeby.

Na przykład, oto Person klasa z jednym static mienia i jednej nieruchomości Klasa:

class Person { 
    static var count: Int { 
     return 250 
    } 

    class var averageAge: Double { 
     return 30 
    } 
} 

Jeśli stworzyliśmy klasę Student przez dziedziczenie z Person, próbując zastąpić count (właściwość statyczna) nie doprowadzi do kompilacji, podczas gdy próbuje zastąpić averageAge (właściwość klasa) jest OK:

class Student: Person { 
    // THIS ISN'T ALLOWED 
    override static var count: Int { 
     return 150 
    } 

    // THIS IS ALLOWED 
    override class var averageAge: Double { 
     return 19.5 
    } 
}