2014-11-01 12 views
52

bemerkte ich, dass der Compiler lässt mich nicht eine gespeicherte Eigenschaft mit einer anderen gespeicherten Wert außer Kraft setzen (die ungerade scheint):Aufschalten einer gespeicherten Eigenschaft in Swift

class Jedi { 
    var lightSaberColor = "Blue" 
} 


class Sith: Jedi { 
    override var lightSaberColor = "Red" // Cannot override with a stored property lightSaberColor 
} 

Allerdings bin ich, dies zu tun erlaubt mit eine berechnete Eigenschaft:

class Jedi { 
    let lightSaberColor = "Blue" 
} 


class Sith: Jedi { 
    override var lightSaberColor : String{return "Red"} 

} 

Warum darf ich keinen anderen Wert geben?

Warum ist das Überschreiben einer gespeicherten Eigenschaft ein Greuel und macht es mit einem berechneten Koscher? Was haben sie gedacht?

+0

möglich Duplikat [Aufschalten Super Eigenschaft mit unterschiedlicher Art in Swift] (http://stackoverflow.com/questions/24094158/overriding-superclass-property-with-different-type-in-swift) –

Antwort

34

Warum darf ich nicht einfach einen anderen Wert angeben?

Sie dürfen einem vererbten Eigentum definitiv einen anderen Wert geben. Sie können es tun, wenn Sie die Eigenschaft in einem Konstruktor initialisieren, die diesen Anfangswert nimmt und einen anderen Wert aus der abgeleiteten Klasse übergeben:

class Jedi { 
    // I made lightSaberColor read-only; you can make it writable if you prefer. 
    let lightSaberColor : String 
    init(_ lsc : String = "Blue") { 
     lightSaberColor = lsc; 
    } 
} 

class Sith : Jedi { 
    init() { 
     super.init("Red") 
    } 
} 

let j1 = Jedi() 
let j2 = Sith() 

println(j1.lightSaberColor) 
println(j2.lightSaberColor) 

eine Eigenschaft Aufschalten ist nicht das gleiche wie ihm einen neuen Wert zu geben - es ist eher wie eine Klasse eine andere Eigenschaft geben. Dies geschieht in der Tat, wenn Sie eine berechnete Eigenschaft überschreiben: Der Code, der die Eigenschaft in der Basisklasse berechnet, wird durch Code ersetzt, der die Überschreibung für diese Eigenschaft in der abgeleiteten Klasse berechnet.

[Ist es] möglich, die tatsächlich gespeicherte Eigenschaft zu überschreiben, d. H. lightSaberColor, die ein anderes Verhalten hat?

Abgesehen von Beobachtern haben gespeicherte Eigenschaften kein Verhalten, es gibt also wirklich nichts zu überschreiben. Durch den oben beschriebenen Mechanismus ist es möglich, der Eigenschaft einen anderen Wert zu geben. Genau das versucht das Beispiel in der Frage mit einer anderen Syntax.

+2

@MaxMacLeod Abgesehen von Beobachtern haben gespeicherte Eigenschaften kein Verhalten, daher gibt es dort wirklich nichts, was überschrieben werden könnte. Er wollte einer gespeicherten Eigenschaft einen anderen Wert in der Unterklasse geben, aber er war sich nicht sicher über den Mechanismus, um dies zu erreichen. Die Antwort erklärt, wie es in Swift gemacht werden kann. Es tut mir leid für die späte Antwort, es scheint, dass dein Kommentar genug Verwirrung verursacht, um Downvotes anzulocken, also habe ich beschlossen zu erklären, was los ist. – dasblinkenlight

10

Sie wollen wahrscheinlich einen anderen Wert auf die Eigenschaft assing:

class Jedi { 
    var lightSaberColor = "Blue" 
} 


class Sith: Jedi { 
    override init() { 
     super.init() 
     self.lightSaberColor = "Red" 
    } 
} 
+7

Gleiches gilt für obigen Kommentar –

17

Für mich Ihr Beispiel funktioniert nicht in Swift 3.0.1.

in Spielplatz Eingetragen diesen Code:

class Jedi { 
    let lightsaberColor = "Blue" 
} 

class Sith: Jedi { 
    override var lightsaberColor : String{return "Red"} 
} 

Wirft Fehler bei der Kompilierung in Xcode:

kann nicht unveränderlich außer Kraft setzen 'lassen' Eigentum 'lightsaberColor' mit dem Getter eines 'var'

Nein, Sie können den Typ einer gespeicherten Eigenschaft nicht ändern. Das Likov-Substitutionsprinzip erzwingt, damit eine Unterklasse an einer Stelle verwendet werden kann, an der die Oberklasse gesucht wird.

Wenn Sie es jedoch zu var ändern und daher die set in der gezählten Eigenschaft hinzufügen, können Sie die gespeicherte Eigenschaft mit einer gezählten Eigenschaft des gleichen Typs überschreiben.

class Jedi { 
    var lightsaberColor = "Blue" 
} 


class Sith: Jedi { 
    override var lightsaberColor : String { 
     get { 
      return "Red" 
     } 
     set { 
      // nothing, because only red is allowed 
     } 
    } 
} 

Dies ist möglich, weil es sinnvoll sein kann, von gespeicherter Eigenschaft zu berechneter Eigenschaft zu wechseln.

Überschreiben Sie jedoch eine gespeicherte var Eigenschaft mit einer gespeicherten var Eigenschaft macht keinen Sinn, weil Sie nur den Wert der Eigenschaft ändern können.

Sie können eine gespeicherte Eigenschaft mit einer gespeicherten Eigenschaft jedoch nicht überschreiben.


Ich würde nicht sagen Sith Jedi :-P sind. Daher ist klar, dass dies nicht funktionieren kann.

3
class SomeClass { 
    var hello = "hello" 
} 
class ChildClass: SomeClass { 
    override var hello: String { 
     set { 
      super.hello = newValue 
     } 
     get { 
      return super.hello 
     }  
    } 
} 
+5

Während dieses Code-Snippet die Frage lösen kann, [hilft eine Erklärung] (http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) wirklich Verbessere die Qualität deines Posts. Denken Sie daran, dass Sie die Frage für Leser in der Zukunft beantworten, und diese Leute könnten die Gründe für Ihren Codevorschlag nicht kennen. – DimaSan

4

Für Swift 4 von Apple's documentation:

Sie können eine geerbte Instanz außer Kraft setzen oder Eigenschaft Typ Ihre eigenen Getter und Setter für diese Eigenschaft zur Verfügung zu stellen, oder Eigenschaft Beobachter in den Aktivieren Sie die überschreibende Eigenschaft, um zu beobachten, wenn sich der zugrunde liegende Eigenschaftswert ändert, wenn .

Verwandte Themen