Я заметил, что компилятор не позволяет мне переопределить сохраненное свойство другим сохраненным значением (что кажется странным):
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"}
}
Почему мне не разрешено присвоить ему другое значение?
Почему переопределение сохраненного свойства является мерзостью, а выполнение этого - кошерным? Что где они думают?
inheritance
swift
properties
overriding
cfischer
источник
источник
Ответы:
Вы определенно можете присвоить унаследованному свойству другое значение. Вы можете сделать это, если инициализируете свойство в конструкторе, который принимает это начальное значение, и передаете другое значение из производного класса:
Переопределение свойства - это не то же самое, что присвоение ему нового значения - это больше похоже на присвоение классу другого свойства. Фактически, именно это и происходит, когда вы переопределяете вычисляемое свойство: код, вычисляющий свойство в базовом классе, заменяется кодом, который вычисляет переопределение для этого свойства в производном классе.
За исключением наблюдателей, сохраненные свойства не имеют поведения, поэтому там действительно нечего переопределять. Присвоение собственности другого значения возможно с помощью описанного выше механизма. Это именно то, что пытается достичь пример в вопросе, с другим синтаксисом.
источник
Для меня ваш пример не работает в Swift 3.0.1.
Я ввел на детской площадке этот код:
Выдает ошибку во время компиляции в Xcode:
Нет, вы не можете изменить тип сохраняемой собственности. Принцип замены Лискова вынуждает вас разрешить использование подкласса там, где требуется суперкласс.
Но если вы измените его на
var
и, следовательно, добавитеset
в вычисляемое свойство, вы можете переопределить сохраненное свойство вычисляемым свойством того же типа.Это возможно, потому что имеет смысл переключиться с сохраненного свойства на вычисляемое.
Но переопределение сохраненного
var
свойства на сохраненноеvar
свойство не имеет смысла, потому что вы можете изменить только значение свойства.Однако вы можете вообще не заменять сохраненное свойство сохраненным свойством.
Я бы не сказал, что ситхи - джедаи :-P. Поэтому ясно, что это не может работать.
источник
источник
Вероятно, вы захотите присвоить этому свойству другое значение:
источник
Для Swift 4 из документации Apple :
источник
В Swift это, к сожалению, невозможно. Лучшая альтернатива следующая:
источник
У меня была такая же проблема, чтобы установить константу для контроллера представления.
Поскольку я использую построитель интерфейса для управления представлением, я не могу его использовать
init()
, поэтому мой обходной путь был аналогичен другим ответам, за исключением того, что я использовал вычисляемую переменную только для чтения как в базовом, так и в унаследованном классах.источник
Если вы попытаетесь сделать это в Swift 5, вас встретит
Лучше всего объявить его как вычисляемое свойство.
Это работает, поскольку мы просто переопределяем
get {}
функциюисточник
Swift не позволяет вам переопределить переменную.
stored property
Вместо этого вы можете использоватьcomputed property
Это более очевидно при сравнении с Java, где поле класса не может быть переопределено и не поддерживает полиморфизм, потому что определяется во время компиляции (выполняется эффективно). Это называется скрытием переменной [О программе] Не рекомендуется использовать эту технику, потому что ее трудно читать / поддерживать
[Свойство Swift]
источник
Вы также можете использовать функцию для переопределения. Это не прямой ответ, но может обогатить эту тему)
Класс А
Класс B: A
источник