Переопределение сохраненного свойства в Swift
Я заметил, что компилятор не позволяет мне переопределить сохраненное свойство с другим сохраненным значением (что кажется странным):
class Jedi {
var lightSaberColor = "Blue"
}
class Sith: Jedi {
override var lightSaberColor = "Red" // Cannot override with a stored property lightSaberColor
}
однако мне разрешено делать это с помощью вычисляемого свойства:
class Jedi {
let lightSaberColor = "Blue"
}
class Sith: Jedi {
override var lightSaberColor : String{return "Red"}
}
почему я не могу дать ему другое значение?
почему переопределение с сохраненным свойством является мерзостью и делает это с вычисленным кошерным? А что они думают?
5 ответов:
почему я не могу просто дать ему другое значение?
вы определенно можете дать наследуемому свойству другое значение. Это можно сделать, если инициализировать свойство в конструкторе, который принимает это начальное значение, и передать другое значение из производного класса:
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)переопределение свойства-это не то же самое, что дать ему новое значение - это больше похоже на предоставление классу другого свойства. На самом деле, это то, что происходит, когда вы переопределяете вычисленное свойство: код, который вычисляет свойство в базовом классе заменить по коду, который вычисляет переопределение для этого свойства в производном классе.
[можно ли] переопределить фактическое сохраненное свойство, т. е.
lightSaberColorэто имеет какое-то другое поведение?кроме наблюдателей, сохраненные свойства не имеют поведения, поэтому там действительно нечего переопределять. Придание свойству другого значения-это возможно через механизм, описанный выше. Это делает именно то, что пример в вопросе пытается достичь, с другим синтаксисом.
для меня ваш пример не работает в Swift 3.0.1 .
ввел в площадку этот код:
class Jedi { let lightsaberColor = "Blue" } class Sith: Jedi { override var lightsaberColor : String { return "Red" } }выдает ошибку во время компиляции в Xcode:
невозможно переопределить неизменяемое свойство' let 'lightsaberColor' с помощью геттера 'var'
нет, вы не можете изменить тип хранимого имущества. Принцип Подстановки Лискова сил вы позволяете использовать подкласс в месте, где суперкласс находится в розыске.
но если вы измените его на
varи поэтому добавитьsetв вычисляемом свойстве можно переопределить сохраненное свойство вычисляемым свойством того же типа.class Jedi { var lightsaberColor = "Blue" } class Sith: Jedi { override var lightsaberColor : String { get { return "Red" } set { // nothing, because only red is allowed } } }это возможно, потому что имеет смысл переключиться с сохраненного свойства на вычисляемое свойство.
но переопределить сохраненный
varсвойство с сохраненнымvarсобственность не имеет смысла, потому что вы можете только изменить значение свойство.однако вы не можете переопределить сохраненное свойство с сохраненным свойством вообще.
я бы не сказал, что Ситы являются джедаями: - P. Поэтому понятно, что это не может работать.
вероятно, вы хотите определить другое значение свойства:
class Jedi { var lightSaberColor = "Blue" } class Sith: Jedi { override init() { super.init() self.lightSaberColor = "Red" } }
для Swift 4, от документация Apple:
можно переопределить унаследованный экземпляр или свойство типа для предоставления собственные геттер и сеттер для этого свойства, или добавить наблюдатели собственность включить переопределение свойств, которые необходимо соблюдать при значение базового свойства изменяется.
class SomeClass { var hello = "hello" } class ChildClass: SomeClass { override var hello: String { set { super.hello = newValue } get { return super.hello } } }
Comments