Reputation: 5169
I looking for a way which permits to override an optional attribute from a superclass with a different type.
If I test something like this:
protocol protocol1
{
func testOne()
}
protocol protocol2 : protocol1
{
func testTwo()
}
class class1
{
var toto : protocol1?
init()
{
}
}
class class2 : class1
{
override var toto : protocol2?
}
let test = class2()
I've got an error in this line: override var toto : protocol2?
Property 'toto' with type 'protocol2' cannot override a property with type 'protocol1'
I've already google it and I found this post but it's for non-optional attribute only.
Upvotes: 4
Views: 1302
Reputation: 72760
The answer in the question you linked doesn't do what you think. It doesn't change the type of a property defined in a protocol or superclass, it just adds a new property.
Swift (and I think any object oriented language) doesn't allow to redefine the type of a property, even if the new type is a subclass/subprotocol of the original type. I've explained that in the comments section of my answer to another similar question.
What you can do? Add a new computed property in class
which attempts to downcast protocol1
to protocol2
, and return nil
if not possible:
class class2 : class1
{
var toto2: protocol2? {
if let toto2 = self.toto as? protocol2 {
return toto2
} else {
return nil
}
}
}
Note that in order for the downcast to work you have to define both protocols as objc compatible
@objc protocol protocol1
{
func testOne()
}
@objc protocol protocol2 : protocol1
{
func testTwo()
}
Below the code I used for testing in playground:
@objc protocol protocol1
{
func testOne()
}
@objc protocol protocol2 : protocol1
{
func testTwo()
}
class classFromProtocol1 : protocol1 {
func testOne() {
}
}
class classFromProtocol2: protocol2 {
func testOne() {
}
func testTwo() {
}
}
class class1
{
var toto : protocol1?
init()
{
}
}
class class2 : class1
{
var toto2: protocol2? {
if let toto2 = self.toto as? protocol2 {
return toto2
} else {
return nil
}
}
}
let test = class2()
test.toto = classFromProtocol1()
test.toto // prints {classFromProtocol1}
test.toto2 // prints nil, because toto contains an instance of classFromProtocol1
test.toto = classFromProtocol2()
test.toto // prints {classFromProtocol2}
test.toto2 // prints {classFromProtocol2}
Upvotes: 2