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.
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*:
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()”).
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.
Nevin
On Tue, Sep 20, 2016 at 8:01 AM, Zhao Xin via swift-evolution > <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Thank you to Игорь Никитин and Adrian Zubarev. Now I can convince
myself for this behavior.
As Adrian's example shows, there is no `bar()` implemented in `class
A`, so there is no `override func bar()` in class B`. My thought
that `self.bar()` would do the same as `(self as! B).bar()`, is called
"dynamic binding", which is basing on the `override`. Since there is no
`override`, there is no "dynamic binding". I thought "dynamic binding"
was basing on dynamic type of `self`. It was not. I was wrong.
The behavior is clear now. In class A's `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's `(self as! B).bar()`, as
`class B` contains the implementation of `bar()`, the runtime calls it.
Zhaoxin
On Tue, Sep 20, 2016 at 4:21 PM, Adrian Zubarev via swift-evolution > <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
I can’t tell you the reason, but to me it feels like it’s doing the
following thing:
>+ - - (Type: B) - - + | | | func bar() + - + (Type: A) - - + < - -
- - - - - - - - - - - - - - - - - - + | | | | + - - - - - - - +
func output() + - + (Protocol: Foo) - - + — - self.bar() - + -
(self as! B).bar() - + | | | | + - - - - - - - + (default) func
bar() | <- - - - - - - - + | | + - - - - - - - - - - - - + |
>class A:Foo { func bar() {} func output() { print(type(of:self))
self.bar() (self as! B).bar() } } class B:A { override func bar() {
print("I am B.") } } |
Would solve this temporarily.
And there we are again with the same discussion if custom
implementation of protocol members, which have default
implementation, should have the |override| keyword or not.
Imagine your code like this (not valid code):
>protocol Foo { func bar() } extension Foo { func bar() { print("I
am bar.") } } class A : Foo { func output() { print(type(of:self))
default.bar() // fallback an call directly the default
implementation whenever needed self.bar() // will print "I am bar."
on A().output() but should print "I am B." if Self == B (self as!
B).bar() } } class B : A { override func bar() { print("I am B.") } } |
I still think default implementations should be called through
something like |default.| + whenever you override a default
implementation you’d need |override|. There is a discussion going
on: |Mark protocol methods with their protocol|. I clearly did not
solved your issue, but I might have wake your interest to
participate. ;)
--
Adrian Zubarev
Sent with Airmail
Am 20. September 2016 um 04:13:22, Zhao Xin via swift-users
(swift-users@swift.org <mailto:swift-users@swift.org>) schrieb:
See below code.
protocol Foo {
func bar()
}
extension Foo {
func bar() {
print("I am bar.")
}
}
class A:Foo {
func output() {
print(type(of:self)) // prints "B".
self.bar() // prints "I am bar."
(self as! B).bar() // prints "I am B."
}
}
class B:A {
func bar() {
print("I am B.")
}
}
let b = B()
b.output()
I thought `self.bar()` would do the same as `(self as! B).bar()`.
It didn't. In my opinion, `type(of:self) is B.type`, so they
should be the same, shouldn't they?
Zhaoxin
_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users
<https://lists.swift.org/mailman/listinfo/swift-users>
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
<https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
<https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution