web-dev-qa-db-fra.com

Swift remplacer les variables d'instance

Je sais que cette réponse a déjà été publiée sous une autre forme ici, mais j'aimerais en savoir plus sur la substitution des variables d'instance dans Swift.

Disons que j'ai ce code

class BaseView:UIView{
 let someVariable:Int = 1
 // do some work with someVariable
}

class ExtendedView:BaseView{
 let someVariable:Int = 2
}

D'accord. D'après ce que j'ai lu, la constante nécessite un préfixe de remplacement. D'autres réponses ont dit que je devrais déclarer le setter et le getter? Pourquoi? Je me fiche vraiment de ces deux-là. J'ai juste besoin que la valeur soit remplacée. Je ne peux pas vraiment utiliser la substitution init car j'hérite de UIView et cela pourrait être assez dangereux (je pense).

Toutes les suggestions sont les bienvenues.

30

Comme vous le dites, vous ne pouvez pas simplement redéfinir une constante dans une sous-classe (c'est une constante, après tout). L'erreur que vous obtenez est "Impossible de remplacer avec une propriété stockée". Il semble possible de remplacer un var, cependant, lorsque je modifie le let someVariable à var someVariable J'obtiens "une utilisation ambiguë de 'someVariable'" lorsque j'y accède dans la sous-classe (remarque - la même chose se produit si j'utilise override ou non).

La solution la plus simple consiste à utiliser un getter. C'est vraiment une fonction, vous pouvez donc la remplacer avec plaisir, la variable de support sera gérée pour vous, et si vous ne fournissez pas de setter ... elle sera constante pour chaque classe:

class BaseView: UIView {
    var someVariable: Int { get { return 1 } }
    // do some work with someVariable
}

class ExtendedView: BaseView {
    override var someVariable: Int { get { return 2 } }
}

let a = BaseView()
a.someVariable // 1
let b = ExtendedView()
b.someVariable // 2

Comme le commentateur @ user3633673 le fait remarquer, si vous seulement avez un getter (et non un setter), vous pouvez supprimer le get, mais je l'ai laissé pour plus de clarté du principe. Voici la même chose sans elle ...

class BaseView: UIView {
    var someVariable: Int { return 1 }
    // do some work with someVariable
}

class ExtendedView: BaseView {
    override var someVariable: Int { return 2 }
}

let a = BaseView()
a.someVariable // 1
let b = ExtendedView()
b.someVariable // 2
61
Grimxn