Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding a stored property in Swift

People also ask

Can we override stored property in Swift?

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).

How do you override properties in Swift?

In swift to override inherited properties or methods in subclass we use override keyword which will tells the compiler to check the overriding method or property definition matches with the base class or not.

How to override a method in Swift?

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.

What is stored property in IOS Swift?

In its simplest form, a stored property is a constant or variable that's stored as part of an instance of a particular class or structure. Stored properties can be either variable stored properties (introduced by the var keyword) or constant stored properties (introduced by the let keyword).


Why am I not allowed to just give it another value?

You are definitely allowed to give an inherited property a different value. You can do it if you initialize the property in a constructor that takes that initial value, and pass a different value from the derived class:

class Jedi {
    // I made lightSaberColor read-only; you can make it writable if you prefer.
    let lightSaberColor : String
    init(_ lsc : String = "Blue") {
        lightSaberColor = lsc;
    }
}

class Sith : Jedi {
    init() {
        super.init("Red")
    }
}

let j1 = Jedi()
let j2 = Sith()

println(j1.lightSaberColor)
println(j2.lightSaberColor)

Overriding a property is not the same as giving it a new value - it is more like giving a class a different property. In fact, that is what happens when you override a computed property: the code that computes the property in the base class is replaced by code that computes the override for that property in the derived class.

[Is it] possible to override the actual stored property, i.e. lightSaberColor that has some other behavior?

Apart from observers, stored properties do not have behavior, so there is really nothing there to override. Giving the property a different value is possible through the mechanism described above. This does exactly what the example in the question is trying to achieve, with a different syntax.


For me, your example does not work in Swift 3.0.1.

I entered in the playground this code:

class Jedi {
    let lightsaberColor = "Blue"
}

class Sith: Jedi {
    override var lightsaberColor : String {
        return "Red"
    }
}

Throws error at compile time in Xcode:

cannot override immutable 'let' property 'lightsaberColor' with the getter of a 'var'

No, you can not change the type of stored property. The Liskov Substitution Principle forces you to allow that a subclass is used in a place where the superclass is wanted.

But if you change it to var and therefore add the set in the computed property, you can override the stored property with a computed property of the same type.

class Jedi {
    var lightsaberColor = "Blue"
}


class Sith: Jedi {
    override var lightsaberColor : String {
        get {
            return "Red"
        }
        set {
            // nothing, because only red is allowed
        }
    }
}

This is possible because it can make sense to switch from stored property to computed property.

But override a stored var property with a stored var property does not make sense, because you can only change the value of the property.

You can, however, not override a stored property with a stored property at all.


I would not say Sith are Jedi :-P. Therefore it is clear that this can not work.


class SomeClass {
    var hello = "hello"
}
class ChildClass: SomeClass {
    override var hello: String {
        set {
            super.hello = newValue
        }
        get {
            return super.hello
        }    
    }
}

You probably want to assign another value to the property:

class Jedi {
    var lightSaberColor = "Blue"
}


class Sith: Jedi {
    override init() {
        super.init()
        self.lightSaberColor = "Red"
    }
}