Zauważyłem, że kompilator nie pozwala mi zastąpić przechowywanej właściwości inną przechowywaną wartością (co wydaje się dziwne):
class Jedi {
var lightSaberColor = "Blue"
}
class Sith: Jedi {
override var lightSaberColor = "Red" // Cannot override with a stored property lightSaberColor
}
Jednak mogę to zrobić z obliczoną właściwością:
class Jedi {
let lightSaberColor = "Blue"
}
class Sith: Jedi {
override var lightSaberColor : String{return "Red"}
}
Dlaczego nie mogę nadać mu innej wartości?
Dlaczego nadpisywanie przechowywanej własności jest obrzydliwością, a robienie tego z obliczoną wartością koszerną? Co oni myślą?
inheritance
swift
properties
overriding
cfischer
źródło
źródło
Odpowiedzi:
Zdecydowanie możesz nadać odziedziczonej własności inną wartość. Możesz to zrobić, jeśli zainicjujesz właściwość w konstruktorze, który przyjmuje tę wartość początkową i przekażesz inną wartość z klasy pochodnej:
Przesłonięcie właściwości to nie to samo, co nadanie jej nowej wartości - bardziej przypomina nadanie klasie innej właściwości. W rzeczywistości dzieje się tak, gdy zastępujesz obliczoną właściwość: kod, który oblicza właściwość w klasie bazowej, jest zastępowany kodem, który oblicza przesłonięcie dla tej właściwości w klasie pochodnej.
Oprócz obserwatorów przechowywane właściwości nie mają zachowania, więc tak naprawdę nie ma nic do zastąpienia. Nadanie nieruchomości innej wartości jest możliwe dzięki mechanizmowi opisanemu powyżej. Robi to dokładnie to, co przykład w pytaniu próbuje osiągnąć, z inną składnią.
źródło
Dla mnie twój przykład nie działa w Swift 3.0.1.
Na placu zabaw wpisałem ten kod:
Zgłasza błąd podczas kompilacji w Xcode:
Nie, nie możesz zmienić typu przechowywanej właściwości. Zasada Zastępstwa Liskova zmusza cię do zezwolenia na użycie podklasy w miejscu, w którym potrzebna jest nadklasa.
Ale jeśli zmienisz to na
var
i w związku z tym dodaszset
właściwość obliczoną, możesz zastąpić właściwość przechowywaną właściwością obliczoną tego samego typu.Jest to możliwe, ponieważ przełączenie się z właściwości przechowywanej na właściwość obliczoną może mieć sens.
Jednak zastąpienie
var
właściwości przechowywanej właściwością przechowywanąvar
nie ma sensu, ponieważ można zmienić tylko wartość właściwości.Nie można jednak w ogóle zastąpić właściwości przechowywanej właściwością przechowywaną.
Nie powiedziałbym, że Sithowie są Jedi :-P. Dlatego jasne jest, że to nie może działać.
źródło
źródło
Prawdopodobnie chcesz przypisać inną wartość właściwości:
źródło
W przypadku Swift 4 z dokumentacji Apple :
źródło
W Swift nie jest to niestety możliwe. Najlepsza alternatywa to:
źródło
Miałem ten sam problem, aby ustawić stałą dla kontrolera widoku.
Ponieważ używam konstruktora interfejsu do zarządzania widokiem, nie mogę go używać
init()
, więc moje obejście było podobne do innych odpowiedzi, z wyjątkiem tego, że użyłem obliczonej zmiennej tylko do odczytu zarówno dla klas podstawowych, jak i dziedziczonych.źródło
Jeśli spróbujesz to zrobić w Swift 5, zostaniesz powitany przez
Najlepszym rozwiązaniem jest zadeklarowanie tego jako obliczonej właściwości.
Działa to, ponieważ właśnie zastępujemy
get {}
funkcjęźródło
Swift nie pozwala na przesłonięcie zmiennej
stored property
Zamiast tego możesz użyćcomputed property
Jest to bardziej czytelne w porównaniu z Javą, gdzie pole klasy nie może być nadpisane i nie obsługuje polimorfizmu, ponieważ jest zdefiniowane w czasie kompilacji (działa wydajnie). Nazywa się to ukrywaniem zmiennej [Informacje]. Nie zaleca się korzystania z tej techniki, ponieważ jest ona trudna do odczytania / obsługi
[Swift property]
źródło
Możesz również użyć funkcji do przesłonięcia. To nie jest bezpośrednia odpowiedź, ale może wzbogacić ten temat)
Klasa A
Klasa B: A
źródło