J'ai une situation où j'ai besoin de remplacer le getter d'une propriété.
Disons que nous avons:
public class MyBaseClass {
private var _name: String
public internal(set) var name: String {
get {
return self._name
}
set {
self._name = newValue
}
}
}
Rien d'extraordinaire, je suppose.
Maintenant, si j'essaie de remplacer le getter dans une classe dérivée:
public class MyDerivedClass: MyBaseClass {
public var name: String {
get {
return "Derived - \(super.name)"
}
}
}
J'obtiens l'erreur de compilation: Impossible de remplacer la propriété mutable par la propriété en lecture seule 'nom'.
Si j'essaie d'ajouter le setter et de le remplacer:
public class MyDerivedClass: MyBaseClass {
public internal(set) var name: String {
get {
return "Derived - \(super.name)"
}
set {
super.name = newValue
}
}
}
J'obtiens l'erreur: Le poseur de var de substitution doit être aussi accessible que la déclaration qu'il remplace.
Et si j'essaye ce qui suit:
public class MyDerivedClass: MyBaseClass {
public internal(set) var name: String {
get {
return "Derived - \(super.name)"
}
}
}
Ensuite, le compilateur plante ...
Comment puis-je réussir à remplacer uniquement le getter?
Cela fonctionne pour moi:
public class MyBaseClass {
private var _name: String = "Hi"
public internal(set) var name: String {
get {
return self._name
}
set {
self._name = newValue
}
}
}
public class MyDerivedClass:MyBaseClass {
override public var name: String {
get {
return "Derived - \(super.name)"
}
set {
super._name = newValue
}
}
}
MyDerivedClass().name
MODIFIER
Ce code fonctionne pour moi dans une aire de jeux, en le plaçant dans le fichier Sources -> SupportCode.Swift
public class MyBaseClass {
private var _name: String = "Hi"
public internal(set) var name: String {
get {
return self._name
}
set {
self._name = newValue
}
}
public init() {
}
}
public class MyDerivedClass:MyBaseClass {
override public var name: String {
get {
return "Derived - \(super.name)"
}
set {
// do nothing
}
}
public override init() {
}
}
C'est un peu un bodge car je reçois le même avertissement que vous que internal(set)
ne peut pas être placé avant la variable de sous-classe surchargée. C'est peut-être un bug. Et aussi je triche pour m'assurer que le setter de la classe dérivée ne fait rien.
Une utilisation plus courante de internal(set)
ou private(set)
est d'avoir un code comme celui-ci, qui est similaire à celui de la documentation:
public class MyBaseClass {
public private(set) var _name: String = "Hi"
public var name: String {
get {
return self._name
}
set {
self._name = newValue
}
}
public init() {
}
}
public class MyDerivedClass:MyBaseClass {
override public var name: String {
get {
return "Derived - \(super.name)"
}
set {
super._name = newValue
}
}
public override init() {
}
}
Ici, le setter peut être lu directement avec MyDerivedClass()._name
mais il ne peut pas être modifié, par ex. cette MyDerivedClass()._name = "Fred"
soulèverait une erreur mais MyDerivedClass().name = "Fred"
serait OK.
MyBaseClass ne compile pas car:
Donc, tout d'abord, nous devons ajouter un initialiseur approprié à MyBaseClass
public class MyBaseClass {
private var _name: String
public internal(set) var name: String {
get { return self._name }
set { self._name = newValue }
}
init(name : String){
_name = name
}
}
Maintenant, nous pouvons déclarer MyDerivedClass
qui remplace la propriété calculée:
Voici le code:
public class MyDerivedClass: MyBaseClass {
public override var name: String {
get { return "Derived - \(super.name)" }
set { super.name = newValue }
}
}
De mon terrain de jeu:
let somethingWithAName = MyDerivedClass(name: "default name")
println(somethingWithAName.name) // > "Derived - default name"
somethingWithAName.name = "another name"
println(somethingWithAName.name) // > "Derived - another name"