Vasyl Khmil
Vasyl Khmil

Reputation: 2557

Overriding properties in swift

For example a have a first class

public class MyBaseButton: UIButton {

    public var weight: Double = 1.0

    public var text: String? {
        get {
            return self.titleForState(.Normal)
        }
        set {
            return self.setTitle(newValue, forState: .Normal)
        }
    }
}

And inherited class:

public class SomeButton: SomeBaseButton {

    override public var text: String? = "text"
    override public var weight: Double = 2.0
}

So, the logic is that SomeClass define own text and weight. But I'm getting an errors:

For text: "Cannot override with a stored property 'text'"

For weight: "Cannot override with a stored property 'weight'"

Upvotes: 40

Views: 53841

Answers (4)

Aggressor
Aggressor

Reputation: 13549

In the above you have a getter and a setter.

When you override it, you are just assigning it a value.

Instead set up the setter and getter as you have above.

var _text:Text

   override public var text: String? {
            get {
                return _text
            }
            set {
                _text = newValue
            }
        }

Upvotes: 4

Stefan Arentz
Stefan Arentz

Reputation: 34935

Interestingly this works just fine in pure Swift classes. For example, this works as expected:

public class FooButton {
    public var weight: Double = 1.0
}

public class BarButton: FooButton {
    override public var weight: Double = 2.0
}

The reason it does not work for you is because you are working with Objective-C classes: since UIButton is an Objective-C class, all its subclasses will be too. Because of that, the rules seem to be a bit different.

Xcode 6.3 is actually a bit more informative. It shows the following two errors:

Getter for "weight" overrides Objective-C method "weight" from superclass "FooButton" Setter for "weight" overrides Objective-C method "setWeight:" from superclass "Foobutton"

Since the following does work ...

public class BarButton: FooButton {
    override public var weight: Double {
        get {
            return 2.0
        }
        set {
            // Do Nothing
        }
    }
}

... my guess is that these methods are simply not synthesized correctly.

I wonder if this is a compiler bug. Or a shortcoming. Because I think it could handle the case.

Maybe the Swift designers thought that in case of overriding weight you could also simply set it to a different value in your initializer. Hm.

Upvotes: 58

pkamb
pkamb

Reputation: 34983

I ran into this issue when trying to override the NSPredicateRowEditor templateViews property in Swift 3.

Superclass property to override:

open var templateViews: [NSView] { get }

Override like so:

class CustomRowTemplate: NSPredicateEditorRowTemplate {

    override var templateViews: [NSView] {
        get {
            let templateViews = super.templateViews

            // custom subclass work goes here

            return templateViews
        }
        //set {

        // Superclass property is `get` only, other properties might need a setter

        //}
    }

}

Upvotes: 1

onmyway133
onmyway133

Reputation: 48075

In addition, if someone wants to override property to have dynamic effect, see KVO

class MyClass: NSObject {
    var date = NSDate()
}

class MyChildClass: MyClass {
    dynamic override var date: NSDate {
        get { return super.date }
        set { super.date = newValue }
    }
}

Upvotes: 13

Related Questions