2

Was trying out some different things with Protocl Inheritance in swift when I came upon an issue where it doesn't compile as it claims "Parent does not conform to BaseParent" even though I can't for the life of me understand why. Probably a back to basics moment... Anyway, here is an explanation and the code:

/*
 - To conform to 'BaseParent', you must have a var called 'child' that conforms to 'BaseChild'
 - 'Child' conforms to 'BaseChild'
 - 'Parent' has a property called 'child' which must conform to 'Child' and by extension, 'BaseChild'
 - Therefore, any element assigned to 'child', must conform to 'BaseChild'
 - Therefore, 'Parent' has a var called 'child' that conforms to 'BaseChild'
 - So why does 'Parent' not conform to 'BaseParent'
*/

protocol BaseChild { /* some methods */ }
protocol Child : BaseChild { /* some more methods */ }

protocol BaseParent {
    var child : BaseChild! {get set}
}

class Parent : BaseParent {
    var child : Child!
}

Probably some obvious reason about protocols that I'm missing but if anyone can go into more details I'd appreciate it :)

2
  • The getter is OK as you are returning an object that conforms to BaseChild protocol, but the setter doesn't match. You cannot set any object conforming BaseChild as expected in BaseParent, it expects any object conforming to Child protocol. Commented Sep 14, 2015 at 11:19
  • Of course, makes sense. Add it as the answer and I'll accept it when it lets me. Commented Sep 14, 2015 at 11:20

1 Answer 1

2

The getter of child declared in Parent is OK as it returns an object that conforms to BaseChild! (because Child inherits from BaseChild). But the setter doesn't conform to the declaration of the parent, as it expects any object that conforms to BaseChild protocol, but you are overriding to expect only those that also conform to Child protocol.

As a workaround to keep type safety, you can create a wrapper property in Parent class:

protocol BaseChild { /* some methods */ }
protocol Child : BaseChild { /* some more methods */ }

protocol BaseParent {
    var baseChild : BaseChild! {get set}
}

class Parent : BaseParent {
    var baseChild: BaseChild!
    var child : Child! {
        get { return baseChild as! Child }
        set { baseChild = newValue }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.