[Draft Proposal] Improve protocol inheritance behaviour


(Dale Buckley) #1

Hi All,

This is an inconsistency I've come across a few times now so I thought I
would detail exactly what the inconsistency is and how I think it should
work. This is a bug thats been reported on JIRA, but when commenting on the
issue Doug Gregor pointed out that this should be a proposal rather than a
bug report.

Simply put (or as simply as I can), when inheriting from a class that
conforms to a protocol that has a protocol extension, not all methods
defined in that protocol are implemented by the class as it relies on the
protocol extension implementations. This is fine until that class is
subclassed tries to add it's own implementation of the methods defined in
the protocol even if they aren't implemented in it's parent class. Once
this situation arrises some problems happen if the parent class calls any
of the methods defined in the protocol but not implemented by itself, but
by it's subclass. If the methods are called externally then everything is
fine, but if the methods are called internally by the parent class, the
subclasses implementations are ignored and the protocol extension
implementation is used instead.

It's a long winded problem to describe which is why I have added a code
sample to my draft proposal to help illustrate the problem better. If
anyone has any tips on how to simplify the description of the problem then
I'm all ears!

https://gist.github.com/dlbuckley/1858a7c0b5c027248fe16171d23ba01d

I believe that this proposal should bring a more consistent and expected
behaviour to code when this situation arrises. Let me know if you believe
the same or disagree.

Thanks,

Dale


#2

I agree there is a problem here, and the mental model I want is for the
language to act “as if” the default implementation of the protocol
requirement “had actually been” implemented by each type which uses it.

In particular, if a class uses a default implementation for one of its
protocol requirements, I want its subclasses to use the “override” keyword
when implementing that method. After all the parent class *does* have a
version of that method which can be called, it just happens to have
received that version by default.

So, for the example in your proposal, I would prefer that the subclass
write “override func doTheSecondThing()”.

Nevin


(Jon Hull) #3

+1

···

On Mar 13, 2017, at 11:24 AM, Nevin Brackett-Rozinsky via swift-evolution <swift-evolution@swift.org> wrote:

I agree there is a problem here, and the mental model I want is for the language to act “as if” the default implementation of the protocol requirement “had actually been” implemented by each type which uses it.

In particular, if a class uses a default implementation for one of its protocol requirements, I want its subclasses to use the “override” keyword when implementing that method. After all the parent class *does* have a version of that method which can be called, it just happens to have received that version by default.

So, for the example in your proposal, I would prefer that the subclass write “override func doTheSecondThing()”.

Nevin
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


#4

Also, you don’t have to go through a superclass method to see the
problematic behavior. You can simply use a subclass instance in a variable
of superclass type:

let subclass: MyClass = MySubclass()
subclass.doTheSecondThing()
// Prints “The 'DEFAULT' 2nd method”

Nevin