I know this answer has already been posted in some other form here, but I'd like to understand more about overriding instance variables in swift.
Let's say I have this code
class BaseView:UIView{ let someVariable:Int = 1 // do some work with someVariable } class ExtendedView:BaseView{ let someVariable:Int = 2 }
Ok. From what I read, the constant requires an override prefix. Other answers said that I should declare the setter and getter? Why? I really don't care about those two. I just need the value replaced. I can't really use the init
override because I'm inheriting from UIView and this might be quite dangerous (i think).
Any suggestions are welcomed.
Because instance variables CANNOT be overridden in Java. In Java, only methods can be overridden. When you declare a field with the same name as an existing field in a superclass, the new field hides the existing field. The existing field from the superclass is still present in the subclass, and can even be used ...
Swift requires us to use override func rather than just func when overriding a method – it stops you from overriding a method by accident, and you'll get an error if you try to override something that doesn't exist on the parent class: class Poodle: Dog { override func makeNoise() { print("Yip!") } }
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.
The override keyword also prompts the Swift compiler to check that your overriding class's superclass (or one of its parents) has a declaration that matches the one you provided for the override. This check ensures that your overriding definition is correct.
As you say, you cannot simply redefine a constant in a subclass (it is a constant, after all). The error you get is "Cannot override with a stored property". It does appear to be possible to override a var
, however, when I change the let someVariable
to var someVariable
I get "ambiguous use of 'someVariable'" when I access it in the subclass (note - same thing happens whether I use override
or not).
The simplest solution is to use a getter. This is really a function, so you can happily override it, the backing variable will be managed for you, and if you don't supply a setter ... it will be constant for each class:
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
As commentator @user3633673 points out, if you only have a getter (and not a setter), you can drop the get
, but I left it in for clarity of the principle. Here's the same without it...
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
... and, of course, in Swift 5, you can drop the return
:
class BaseView: UIView { var someVariable: Int { 1 } } class ExtendedView: BaseView { override var someVariable: Int { 2 } }
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