J'ai remarqué que le compilateur ne me laissera pas remplacer une propriété stockée par une autre valeur stockée (ce qui semble étrange):
class Jedi {
var lightSaberColor = "Blue"
}
class Sith: Jedi {
override var lightSaberColor = "Red" // Cannot override with a stored property lightSaberColor
}
Cependant, je suis autorisé à le faire avec une propriété calculée:
class Jedi {
let lightSaberColor = "Blue"
}
class Sith: Jedi {
override var lightSaberColor : String{return "Red"}
}
Pourquoi ne suis-je pas autorisé à lui donner une autre valeur?
Pourquoi le remplacement d'une propriété stockée est-il une abomination et le faire avec une propriété calculée casher? Que pensent-ils?
inheritance
swift
properties
overriding
cfischer
la source
la source
Réponses:
Vous êtes définitivement autorisé à attribuer une valeur différente à une propriété héritée. Vous pouvez le faire si vous initialisez la propriété dans un constructeur qui prend cette valeur initiale et transmettez une valeur différente de la classe dérivée:
Remplacer une propriété n'est pas la même chose que lui donner une nouvelle valeur - c'est plutôt donner à une classe une propriété différente. En fait, c'est ce qui se produit lorsque vous substituez une propriété calculée: le code qui calcule la propriété dans la classe de base est remplacé par du code qui calcule le remplacement pour cette propriété dans la classe dérivée.
En dehors des observateurs, les propriétés stockées n'ont pas de comportement, il n'y a donc vraiment rien à remplacer. Donner à la propriété une valeur différente est possible grâce au mécanisme décrit ci-dessus. Cela fait exactement ce que l'exemple de la question essaie de réaliser, avec une syntaxe différente.
la source
Pour moi, votre exemple ne fonctionne pas dans Swift 3.0.1.
J'ai entré dans l'aire de jeux ce code:
Lève une erreur au moment de la compilation dans Xcode:
Non, vous ne pouvez pas modifier le type de propriété stockée. Le principe de substitution de Liskov vous oblige à autoriser qu'une sous-classe soit utilisée à un endroit où la superclasse est souhaitée.
Mais si vous le remplacez par
var
et par conséquent ajoutez leset
dans la propriété calculée, vous pouvez remplacer la propriété stockée par une propriété calculée du même type.Cela est possible car il peut être judicieux de passer d'une propriété stockée à une propriété calculée.
Mais remplacer une
var
propriété stockée par unevar
propriété stockée n'a pas de sens, car vous ne pouvez modifier que la valeur de la propriété.Cependant, vous ne pouvez pas du tout remplacer une propriété stockée par une propriété stockée.
Je ne dirais pas que les Sith sont des Jedi :-P. Par conséquent, il est clair que cela ne peut pas fonctionner.
la source
la source
Vous souhaitez probablement attribuer une autre valeur à la propriété:
la source
Pour Swift 4, à partir de la documentation Apple :
la source
Dans Swift, ce n'est malheureusement pas possible de le faire. La meilleure alternative est la suivante:
la source
J'ai eu le même problème pour définir une constante pour un contrôleur de vue.
Comme j'utilise le générateur d'interface pour gérer la vue, je ne peux pas l'utiliser
init()
, donc ma solution de contournement était similaire à d'autres réponses, sauf que j'ai utilisé une variable calculée en lecture seule sur les classes de base et héritées.la source
Si vous essayez de faire cela dans Swift 5, vous serez accueilli par un
Votre meilleur pari est de le déclarer comme propriété calculée.
Cela fonctionne car nous remplaçons simplement la
get {}
fonctionla source
Swift ne vous permet pas de remplacer une variable
stored property
Au lieu de cela, vous pouvez utilisercomputed property
C'est plus clair par rapport à Java, où un champ de classe ne peut pas être remplacé et ne prend pas en charge le polymorphisme car il est défini au moment de la compilation (s'exécute efficacement). C'est ce qu'on appelle une variable se cachant [À propos] Il n'est pas recommandé d'utiliser cette technique car elle est difficile à lire / à supporter
[Propriété Swift]
la source
Vous pouvez également utiliser une fonction pour remplacer. Ce n'est pas une réponse directe, mais peut enrichir ce sujet)
Classe A
Classe B: A
la source