当我尝试覆盖属性时出现错误“无法使用只读属性覆盖可变属性”
我在父类(super class)中提供了 get 和 set。
class Card {
var contents:String {
get {
return self.contents
}
set {
self.contents = newValue
}
}
init() {
self.contents = ""
}
}
这是我的子类,我试图在其中覆盖“内容”属性。
class PlayingCard: Card {
override var contents:String { //<-- this is where I get the build error
get {
var rankStrings:Array<String> = PlayingCard.rankStrings()
return rankStrings[Int(self.rank)] + self.suit
}
}
}
我究竟做错了什么?
最佳答案
如果您要重写的属性同时具有 getter 和 setter,则您也需要在子类中同时提供这两者。这是 relevant part from the Swift language guide (强调我的):
You can present an inherited read-only property as a read-write property by providing both a getter and a setter in your subclass property override. You cannot, however, present an inherited read-write property as a read-only property.
如果您没有对该值做任何特殊的事情,那么您通常希望将设置的值传递给基类:
set {
super.contents = newValue
}
你也可以用一个空的 setter 丢弃这个值(虽然我想不出一个好的理由来临时这样做):
set { }
我还想指出,您在 Card
类的 contents
属性中有一个无限循环。当你这样做时:
get {
return self.contents
}
您实际上只是再次调用同一个 getter,创建一个无限循环;你对二传手做同样的事情。 Swift 不会像 Objective-C 那样自动为您的属性创建 ivar,因此您需要自己创建它们。创建该属性的更合适的方法是执行如下操作:
class Card {
private var _contents: String
var contents: String {
get {
return _contents
}
set {
_contents = newValue
}
}
init() {
_contents = ""
}
}
但是,由于您除了在 setter 和 getter 中设置和返回 _contents
之外没有做任何其他事情,所以您可以将其简化为:
class Card {
var contents: String = ""
init() {
}
}
注意:contents
也可能是使用可选 (String?
) 并将其设置为 的不错选择>nil
而不是将其初始化为空字符串。
关于properties - Swift 属性覆盖不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26112254/