When I try to override a property I get an error "can not override mutable property with read-only property"
I have provided get and set in the super class.
class Card { var contents:String { get { return self.contents } set { self.contents = newValue } } init() { self.contents = "" } }
Here is my Subclass where I am trying to override the "contents" property.
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 } } }
What exactly am I doing wrong?
Hi, Swift rules state that any inherited property can be overridden whether it is implemented as a stored or computed property at source (parent class).
In Swift Inheritance, the subclass inherits the methods and properties of the superclass. This allows subclasses to directly access the superclass members. Now, if the same method is defined in both the superclass and the subclass, then the method of the subclass class overrides the method of the superclass.
If the property you're overriding has both a getter and a setter, you need to provide both in your subclass as well. Here's the relevant part from the Swift language guide (emphasis mine):
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.
If you're not doing anything special with the value, then you'll typically want to pass the value being set on to the base class:
set { super.contents = newValue }
You could also just discard the value with an empty setter (although I can't think of a good reason to do this offhand):
set { }
I also wanted to point out that you have an infinite loop in the contents
property in your Card
class. When you you do this:
get { return self.contents }
You're actually just calling that same getter again, creating an infinite loop; you're doing the same with the setter. Swift doesn't create ivars for your properties automatically like Objective-C did, so you need to create them yourself. A more appropriate way to create that property would be to do something like this:
class Card { private var _contents: String var contents: String { get { return _contents } set { _contents = newValue } } init() { _contents = "" } }
However, since you're not doing anything other than setting and returning _contents
in your setter and getter, you can simplify it down to this:
class Card { var contents: String = "" init() { } }
Note: contents
might also be a good candidate for using an optional (String?
) and setting it to nil
rather than initializing it to an empty string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With