protocol FooProtocol {
func bar()
}
// default implementations for protocol requirements
extension FooProtocol {
func bar() { print("default") }
}
// A class inheriting `FooProtocol`
class Foo: FooProtocol {
}
// Override the `bar` function
final class Bar: Foo {
func bar() {
print("bar")
}
}
When I cast bar as any FooProtocol, bar.bar() prints "default"
let bar: (any FooProtocol) = Bar()
bar.bar()
// default
However, in the Foo class, if I implement the bar function,
class Foo: FooProtocol {
// explicitly declare the function
func bar() {
(self as any FooProtocol).bar()
}
}
// now need to override
final class Bar: Foo {
override func bar() {
print("bar")
}
}
let bar: (any FooProtocol) = Bar()
bar.bar()
// bar
Could you explain this behavior please?
As even without Foo implementing the bar function, there is a default implementation. The function body (self as any FooProtocol).bar() should be redundant.
Any suggestions will be greatly appreciated!
PS, when implementing Bar.bar, Xcode would auto add the override keyword, and then emit the error that Method does not override any method from its superclass.
env
$ swift --version
swift-driver version: 1.113 Apple Swift version 6.0 (swiftlang-6.0.0.7.6 clang-1600.0.24.1)
Target: arm64-apple-macosx14.0
That's because Swift resolves methods on protocol conformance statically. It finds default method only from protocol, and IIRC when first implementation in inheritance chain omits it, all child types will be resolved to the default implementation declared within the protocol.
You can search for this on forum, there were many topics over years that run into the same issue.