Der*_*328 21 overriding properties swift ios8
当我尝试覆盖属性时,我收到错误"无法覆盖具有只读属性的可变属性"
我已经在超类中提供了get和set.
class Card {
var contents:String {
get {
return self.contents
}
set {
self.contents = newValue
}
}
init() {
self.contents = ""
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的Subclass,我试图覆盖"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
}
}
}
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
Mik*_*e S 30
如果您要覆盖的属性同时具有getter和setter,则还需要在子类中同时提供这两个属性.这是Swift语言指南(强调我的)中的相关部分:
通过在子类属性覆盖中提供getter和setter,可以将继承的只读属性作为读写属性提供.但是,您不能将继承的读写属性显示为只读属性.
如果您没有对值进行任何特殊操作,那么您通常希望将设置的值传递给基类:
set {
super.contents = newValue
}
Run Code Online (Sandbox Code Playgroud)
你也可以用一个空的setter来丢弃这个值(虽然我想不出有理由这么做):
set { }
Run Code Online (Sandbox Code Playgroud)
我还想指出contents你的Card班级属性中有一个无限循环.当你这样做:
get {
return self.contents
}
Run Code Online (Sandbox Code Playgroud)
你实际上只是再次调用相同的getter,创建一个无限循环; 你对二传手做同样的事情.Swift不会像Objective-C那样自动为您的属性创建ivars,因此您需要自己创建它们.创建该属性的更合适的方法是执行以下操作:
class Card {
private var _contents: String
var contents: String {
get {
return _contents
}
set {
_contents = newValue
}
}
init() {
_contents = ""
}
}
Run Code Online (Sandbox Code Playgroud)
但是,由于除了_contents在setter和getter中设置和返回之外你没有做任何其他事情,你可以将其简化为:
class Card {
var contents: String = ""
init() {
}
}
Run Code Online (Sandbox Code Playgroud)
注意: contents也可能是使用optional(String?)并将其设置为nil而不是将其初始化为空字符串的良好候选者.
编译器错误消息相当简单:Card's contentsproperty is mutable,也就是说它set除了方法之外还有一个方法get。
您的重写仅添加一个get方法,您还需要添加一个set方法。
我想这就是你想要的:
set(newValue) {
rankStrings[Int(self.rank)] = newValue;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18520 次 |
| 最近记录: |