Questions: “Can you call super in a setter?”

k writes: “Can you call super in a setter? e.g. override a setter and call super with a different value?”

Sure. Here’s an example:

class Foo {
    var value: String
    init(value: String) { self.value = value }
}

class SubFoo: Foo {
    override var value: String {
        get { return super.value }
        set { super.value = newValue.lowercased()
        }
    }
}

The SubFoo class works like Foo but lowercases its value on assignment (although not, in this implementation, on initialization). So if you create an instance of the subclass and assign a mixed-case string, the assignment automatically lowercases it and then applies the superclass’s assignment.

let a = Foo(value: "Hello World")
let b = SubFoo(value: "Hello World")
debugPrint(a.value, b.value) // "Hello World", "Hello World"
b.value = "Hello Sailor"
debugPrint(a.value, b.value) // "Hello World", "hello sailor"

I’m not sure if there’s a ton of useful cases for this but it is certainly possible.

2 Comments

  • I tried `set { self.value = newValue.lowercaseString }` and got `EXC_BAD_ACCESS`. So I thought the only way to override a setter method is to use `super` as you did.

    Thanks for sharing.

  • Is your example is a violation of the Liskov substitution principle?
    I think you are altering an inherited behaviour and so making the subclass no longer capable of replacing the super class.