protocol P {
func foo()
}
extension P {
func foo () {
print("P.foo")
}
}
class Base: P {}
class Derived: Base {
func foo() {
print("Derived.foo")
}
}
let obj: P = Derived()
obj.foo() // prints "P.foo", instead of "Derived.foo"
BTW, I used the following trick, and I know this is "ugly".
protocol P {
func foo()
}
protocol PWithDefault {
}
extension P where Self: PWithDefault {
func fooDefault() {
print("P.foo")
}
}
class Base: P, PWithDefault {
// have to explicit write out a dummy `foo` for overriding
func foo() {
fooDefault()
}
}
class Derived: Base {
override func foo() {
print("Derived.foo")
}
}
Still looking forward for this to be officially solved though.
You are right, this is a problem but not sure if there is a good solution. The reason the behavior exists is because extensions do not support polymorphism that includes compile time polymorphism. The answer to why is behind protocols being allowed by structs and enums and those cant'e be extended so dynamic dispatch capabilities are not needed.
The way it is evident is by the fact that even though you would like to think Base class knows foo is implemented because it implements the protocol P but still its child Derived doesn't needs to mark the foo as an overridden function.
The below code will work but I would think that it really doesn't solves your use case as you were probably trying to provide a default implementation (like an abstract class that doesn't exists in Swift)
**protocol** P {
func foo()
}
extension P {
func foo () {
print("P.foo")
}
}
class Base: P {
func foo () {}
}
class Derived: Base {
overridefunc foo() {
print("Derived.foo")
}
}
let obj: P = Derived()
obj.foo() // prints "P.foo", instead of "Derived.foo"
A few videos at the below playlist also cover the polymorphism in swift: