Override extra attribute from superclass with different type in Swift

I am looking for a way that allows you to override an optional attribute from a superclass with a different type.

If I test with 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()

      

There is an error on this line: override var toto : protocol2?

Property 'toto' with type 'protocol2' cannot override a property with type 'protocol1'

I already had this and found this post , but only for an optional attribute.

+3


source to share


1 answer


The answer to the question you linked does not do what you think it does. It doesn't change the type of the property defined in the protocol or superclass, it just adds a new property.

Swift (and I think any OO language) does not allow you to override the type of a property, even if the new type is a subclass / subprotocol of the original type. I explained this in the comment section of my answer to another similar question .

What can you do? Add a new computed property to class

that tries to shrink 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 downcast to work, you need to define both protocols as objc compatible

@objc protocol protocol1
{
    func testOne()
}

@objc protocol protocol2 : protocol1
{
    func testTwo()
}

      

Below is the code I used to test in the 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}

      

+2


source







All Articles