Hello fellow Swift enthusiasts,
I stumbled upon an interesting question on StackOverflow that asks why Swift doesn't complain when overriding a computed property typed as an optional with a property typed non-optional. More precisely, here's the (working) code that is proposed:
class A {
var x: Int? { return nil }
}
class B: A {
override var x: Int { return 0 }
}
While playing around to give a convincing explanation, I noticed this works as well:
class A {
var x: A { return A() }
}
class B: A {
override var x: B { return B() }
}
To me, this would suggest that covariant types are allowed to override a read-only property, which makes sense I guess, as one can't set the property x
on an instance of B
through a variable of type A
.
However, after further investigations, I failed to understand the conditions for such overrides to be accepted or rejected. Indeed, declaring x
as an optional of A
still works, but declaring x
as an array of A
in the base class doesn't seem to be overridable with an array of B
(while my understanding was that Swift arrays are covariant). Furthermore, declaring x
with type Any
doesn't seem to be overridable with any other type in the derived class.
class A { var x: A? { return A() } }
class B: A { override var x: B { return B() } } // OK
class A { var x: [A] { return [A()] } }
class B: A { override var x: [B] { return [B()] } } // Fails
class A { var x: Any { return A() } }
class B: A { override var x: B { return B() } } // Fails
This makes me question if this behavior was intended at all, or if it's just a side effect of allowing supporting covariant method overrides, whose implementation is mentioned in the changelog for Swift 4.0.
Could anyone shed some light on this?
Regards.