<div dir="ltr">I think there is a deeper issue that may be worth exploring here.<div><br></div><div>Notably, when one class presents a member function, its subclasses ought to use “override” when they reimplement that method themselves, regardless of where the superclass’s version comes from.</div><div><div><br></div><div>In the original post, the class “A” expresses (by conforming to protocol “Foo”) that it has a member function “bar()”, and “B” is a subclass of “A” which wants its own definition of “bar()”.</div><div><br></div><div>It seems to me that “B” should not care whether “A” rolled its own implementation of “bar()” or used the default implementation provided by “Foo”.</div><div><br></div><div>From the perspective of “B”, its superclass “A” promises to have a member function “bar()”, so “B” should need to use the `override` keyword just like it would when overriding any other method.</div><div><br></div><div>To illustrate this more clearly, suppose that “Foo” and “A: Foo” are defined in a 3rd-party library, while “B: A” is written in a client module.</div><div><br></div><div>If the library changes to give “A” its own custom implementation of “bar()”, that *should not* affect client code—because the class “A” still conforms to “Foo” so it still is known to have a “bar()” method—but right now it *does*:</div><div><br></div><div>With the status quo, the simple change of moving a function between a protocol extension and a conforming class currently requires downstream source-code modifications in clients (in this case, adding `override` to “B.bar()”).</div><div><br></div><div>I propose that `override` should be required in subclasses on any method which the superclass proffers as a customization point, no matter the provenance of that claim.</div><div><br></div><div>Nevin</div><div><br></div><div><br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Sep 20, 2016 at 8:01 AM, Zhao Xin via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_default"><font face="georgia, serif">Thank you to  Игорь Никитин and Adrian Zubarev. Now I can convince myself for this behavior.</font></div><div class="gmail_default"><font face="georgia, serif"><br></font></div><div class="gmail_default"><span style="font-family:georgia,serif">As Adrian&#39;s example shows, there is no `</span><font face="georgia, serif">bar()` implemented in `class A`, so there is no `override func bar()</font><span style="font-family:georgia,serif">` in class B`. My thought that </span><span style="color:rgb(0,0,0);font-family:georgia,serif;font-size:13px"> </span><span style="color:rgb(0,0,0);font-family:georgia,serif;font-size:13px">`self.bar()` would do the same as `(self as! B).bar()`, is called &quot;dynamic binding&quot;, which is basing on the `override`. Since there is no `override`, there is no &quot;dynamic binding&quot;. I thought &quot;dynamic binding&quot; was basing on dynamic type of `self`. It was not. I was wrong.</span></div><div class="gmail_default"><span style="color:rgb(0,0,0);font-family:georgia,serif;font-size:13px"><br></span></div><div class="gmail_default"><span style="color:rgb(0,0,0);font-family:georgia,serif;font-size:13px">The behavior is clear now. In class A&#39;s `</span><font color="#000000" face="georgia, serif">self.bar()`, the runtime finds that there is no implementation of `bar()` in `class A`, so it calls the `bar` in protocol extension. In class A&#39;s `(self as! B).bar()`, as `class B` contains the implementation of `bar()`, the runtime calls it.</font></div><div class="gmail_default"><span style="color:rgb(0,0,0);font-family:georgia,serif;font-size:13px"><br></span></div><div class="gmail_default"><span style="color:rgb(0,0,0);font-family:georgia,serif;font-size:13px">Zhaoxin</span></div></div><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On Tue, Sep 20, 2016 at 4:21 PM, Adrian Zubarev via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5"><div style="word-wrap:break-word"><div><p>I can’t tell you the reason, but to me it feels like it’s doing the following thing:</p>

<pre><code>+ - - (Type: B) - - +
|                   |
| func bar()    + - + (Type: A) - - +                        &lt; - - - - - - - - - - - - - - - - - - - - +
|               |                   |                                                                  |
+ - - - - - - - + func output() + - + (Protocol: Foo) - - +  — - self.bar() - + - (self as! B).bar() - +
                |               |                         |                   |
                + - - - - - - - + (default) func bar()    |  &lt;- - - - - - - - +
                                |                         |
                                + - - - - - - - - - - - - +
</code></pre>

<pre><code>class A:Foo {
     
    func bar() {}
     
    func output() {
        print(type(of:self))
        self.bar()
        (self as! B).bar()
    }
}

class B:A {

    override func bar() {
        print(&quot;I am B.&quot;)
    }
}
</code></pre>

<p>Would solve this temporarily.</p>

<p>And there we are again with the same discussion if custom implementation of protocol members, which have default implementation, should have the <code>override</code> keyword or not.</p>

<p>Imagine your code like this (not valid code):</p>

<pre><code>protocol Foo {
    func bar()
}

extension Foo {
    func bar() {
        print(&quot;I am bar.&quot;)
    }
}

class A : Foo {
     
    func output() {
         
        print(type(of:self))
        default.bar() // fallback an call directly the default implementation whenever needed
        self.bar() // will print &quot;I am bar.&quot; on A().output() but should print &quot;I am B.&quot; if Self == B
        (self as! B).bar()
    }
}

class B : A {

    override func bar() {
        print(&quot;I am B.&quot;)
    }
}
</code></pre>

<p>I still think default implementations should be called through something like <code>default.</code> + whenever you override a default implementation you’d need <code>override</code>. There is a discussion going on: <code>Mark protocol methods with their protocol</code>. I clearly did not solved your issue, but I might have wake your interest to participate. ;)</p><span><font color="#888888">

<p></p></font></span></div><div><span><font color="#888888"><div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto"><br></div> <br> <div><div style="font-family:helvetica,arial;font-size:13px">-- <br>Adrian Zubarev<br>Sent with Airmail</div></div></font></span><div><div> <br><p>Am 20. September 2016 um 04:13:22, Zhao Xin via swift-users (<a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a>) schrieb:</p> </div></div><blockquote type="cite"><span><div><div></div><div><div><div>





<div dir="ltr">
<div class="gmail_default" style="font-family:georgia,serif">See
below code.</div>
<div class="gmail_default" style="font-family:georgia,serif">
<br></div>
<div class="gmail_default">
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(4,51,255)">
<span>protocol</span>
<span style="color:rgb(0,0,0)">Foo
{</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span> 
 </span> <span style="color:rgb(4,51,255)">func</span>
<span>bar()</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span>}</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px">
<br></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(4,51,255)">
<span>extension</span>
<span style="color:rgb(52,149,175)">Foo</span>
<span style="color:rgb(0,0,0)">{</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span> 
 </span> <span style="color:rgb(4,51,255)">func</span>
<span>bar()
{</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(180,38,26)">
<span style="color:rgb(0,0,0)"> 
     </span> <span style="color:rgb(52,149,175)">print</span><span style="color:rgb(0,0,0)">(</span><span>&quot;I
am bar.&quot;</span><span style="color:rgb(0,0,0)">)</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span> 
  }</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span>}</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px">
<br></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span style="color:rgb(4,51,255)">class</span>
<span>A:</span><span style="color:rgb(52,149,175)">Foo</span>
<span>{</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span> 
 </span> <span style="color:rgb(4,51,255)">func</span>
<span>output()
{</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span> 
     </span> <span style="color:rgb(52,149,175)">print</span><span>(type(of:</span><span style="color:rgb(4,51,255)">self</span><span>))</span>
<span style="color:rgb(0,143,0)">//
prints &quot;B&quot;.</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(0,143,0)">
<span style="color:rgb(0,0,0)"> 
     </span> <span style="color:rgb(4,51,255)">self</span><span style="color:rgb(0,0,0)">.</span><span style="color:rgb(52,149,175)">bar</span><span style="color:rgb(0,0,0)">()</span>
<span>// prints
&quot;I am bar.&quot;</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span> 
      (self</span> <span style="color:rgb(4,51,255)">as</span><span>!</span>
<span style="color:rgb(52,149,175)">B</span><span>).</span><span style="color:rgb(52,149,175)">bar</span><span>()</span>
<span style="color:rgb(0,143,0)">//
prints &quot;I am B.&quot;</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span> 
  }</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span>}</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px">
<br></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span style="color:rgb(4,51,255)">class</span>
<span>B:</span><span style="color:rgb(52,149,175)">A</span>
<span>{</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span> 
 </span> <span style="color:rgb(4,51,255)">func</span>
<span>bar()
{</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span> 
     </span> <span style="color:rgb(52,149,175)">print</span><span>(</span><span style="color:rgb(180,38,26)">&quot;I
am B.&quot;</span><span>)</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span> 
  }</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span>}</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px">
<br></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">
<span style="color:rgb(4,51,255)">let</span>
<span>b =</span>
<span style="color:rgb(52,149,175)">B</span><span>()</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(52,149,175)">
<span>b</span><span style="color:rgb(0,0,0)">.</span><span>output</span><span style="color:rgb(0,0,0)">()</span></p>
<p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(52,149,175)">
<br></p>
<p style="margin:0px;line-height:normal"><font color="#000000" face="georgia, serif">I thought `self.bar()` would do the same as
`(self as! B).bar()`. It didn&#39;t. In my opinion,
 `type(of:self) is B.type`, so they should be the same,
shouldn&#39;t they?</font></p>
<p style="margin:0px;line-height:normal"><font color="#000000" face="georgia, serif"><br></font></p>
<p style="margin:0px;line-height:normal"><font color="#000000" face="georgia, serif">Zhaoxin</font></p>
</div>
</div></div></div>


______________________________<wbr>_________________<span><br>swift-users mailing list<br><a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-users" target="_blank">https://lists.swift.org/mailma<wbr>n/listinfo/swift-users</a><br></span></div></div></span></blockquote></div><div><p></p></div></div><br></div></div>______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailma<wbr>n/listinfo/swift-evolution</a><br>
<br></blockquote></div><br></div>
<br>______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
<br></blockquote></div><br></div>