Swift

2014-11-01 10 views
52

saklı özelliği geçersiz kılma Ben derleyici bana (tuhaf) bir başka saklanan değere sahip bir saklı özelliğini geçersiz izin vermez fark hesaplanan bir özelliği:Swift

class Jedi { 
    let lightSaberColor = "Blue" 
} 


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

} 

Neden başka değer vermek için izin yok?

Neden depolanmış bir özellik ile bir abartıyı geçersiz kılıyor ve hesaplanmış bir koşer ile yapıyor? Nerede düşünüyorlar?

+0

[Swift farklı tip üst sınıf özelliği geçersiz kılma] olası çift (http://stackoverflow.com/questions/24094158/overriding-superclass-property-with-different-type-in-swift) –

cevap

34

Neden başka bir değer vermemize izin verilmiyor?

Devralınan bir mülkün farklı bir değer vermesine kesinlikle izin verilir. Bir özellik geçersiz kılma ona yeni bir değer vererek aynı değildir

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) 

- it: Sen o ilk değerini alır yapıcı tesise başlatmak eğer bunu ve türetilmiş sınıftan farklı bir değer iletebilirsiniz daha çok bir sınıfa farklı bir özellik vermek gibidir. Aslında, hesaplanmış bir özelliği geçersiz kıldığınızda gerçekleşen budur: özel sınıftaki özelliği hesaplayan kod, türetilmiş sınıftaki söz konusu özellik için geçersiz kılma hesaplayan kod ile değiştirilir.

[Bu özellik] başka bir davranışa sahip olan gerçek depolanmış özelliği, yani lightSaberColor geçersiz kılmak mümkün mü?

Gözlemcilerden ayrı olarak, depolanmış özelliklerin davranışı yoktur, bu nedenle geçersiz kılacak hiçbir şey yoktur. Mülkün yukarıda açıklanan mekanizma ile farklı bir değer verilmesi mümkündür. Bu, sorudaki örneğin, farklı bir sözdizimiyle, elde etmeye çalıştığı şeyi tam olarak yapar.

+2

@MaxMacLeod Gözlemciler dışında, depolanmış mülklerin davranışları yoktur, bu yüzden geçersiz kılacak hiçbir şey yoktur. Depolanmış bir mülkün alt sınıfta farklı bir değer vermek istediğini, ancak bunu başarma mekanizmasından emin değildi. Cevap, Swift'de nasıl yapılabileceğini açıklıyor. Geç cevap için özür dilerim, yorumunuz downvotes çekmek için yeterli karışıklığa neden oluyor, bu yüzden neler olduğunu açıklamaya karar verdim. – dasblinkenlight

10

Muhtemelen özelliğine başka bir değer assing istiyorum:

class Jedi { 
    var lightSaberColor = "Blue" 
} 


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

aynıdır Yukarıdaki yorum başına geçerlidir –

17

Benim için senin örneğin Swift 3.0.1 çalışmaz.

class Jedi { 
    let lightsaberColor = "Blue" 
} 

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

Xcode derleme zamanında hata atar: oyun alanında bu kodu girildi

bir 'var'

ait gaz giderici değişmez 'let' özelliği 'lightsaberColor' geçersiz kılamaz

Hayır, kayıtlı bir özelliğin türünü değiştiremezsiniz. Liskov İkame İlkesi , üst sınıfın istendiği yerde bir alt sınıfın kullanılmasına izin vermek için'u zorlar.

Ancak, var olarak değiştirirseniz ve bu nedenle set değerini sayılan özelliğe eklerseniz, depolanan özelliği aynı türde sayılan bir özelliği geçersiz kılabilirsiniz.

class Jedi { 
    var lightsaberColor = "Blue" 
} 


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

Bu, depolanan özellikten hesaplanan özellik arasında geçiş yapmak mantıklı olabileceğinden mümkündür. Ancak depolanmış bir var özelliği ile depolanmış bir var özelliğini geçersiz kılmanız mantıklı değildir, çünkü yalnızca mülkün değerini değiştirebilirsiniz. Ancak, depolanmış bir özelliği kayıtlı bir özelliği geçersiz kılmazsınız.


Ben Sith Jedi :-P demek değildir. Bu nedenle, bunun işe yaramayacağı açıktır. Swift 4 için

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

Bu kod parçacığı sorusunu çözebilirken, [bir açıklama dahil] (http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) gerçekten yardımcı olur Gönderinizin kalitesini iyileştirin. Gelecekte okuyucular için soruyu cevapladığınızı ve bu kişilerin kod önerilerinizin nedenini bilmeyebileceğini unutmayın. – DimaSan

4

, Apple's documentation den:

Bir miras örneğini geçersiz veya bu özellik için kendi özel alıcı ve ayarlayıcı sağlamak veya mülkiyet gözlemci eklenecek özelliği yazabilirsiniz Altında yatan özellik temel özellik değerinin değiştiğini gözlemlemek için etkinleştirin.