I have a protocol Vehicle and its extension like below:
protocol Vehicle {
func Drive()
}
extension Vehicle {
func Stop() {
print("iiiich...")
}
}
And I also have declaration like below for Stop Method
struct Car: Vehicle {
func Drive() {
print("Can Drive")
}
func Stop() {
print("yo stop")
}
}
let myCar = Car()
myCar.Drive()
myCar.Stop()
But its override the Stop Method
// Output
// Can Drive
// yo stop
And as per my requirement I need default method sometime and some time overridden method definition
Hey I got the answers that is to conform the protocol by the object call your default method rather than overriddedn, so we can call both defination as required
let honda: Vehicle = Car()
honda.Drive()
honda.Stop()
// Output
// Can Drive
// iiiich..
When we create a variable without type then this is static dispatch when a object conform a protocol only.
If you need the method declared in the protocol extension, just make the compiler think that the car is of type Vehicle
:
let myCar = Car()
(myCar as Vehicle).Stop()
As already mentioned in the answers, the generic solution is to make sure that the instance that calls Stop()
method is of type Vehicle
(not Car
). Nevertheless I would mention what's the logic behind it.
Personally, I think that there is a possibility to face this issue when it comes to work with the POP paradigm. Protocol extensions is a handy way the apply Polymorphism in our code, however it does leads to this "weird" behavior!
Firstly, keep in mind that it is not a bug. In case of:
let honda: Vehicle = Car()
honda.Drive()
honda.Stop()
there is a manual cast to the honda
as Vehicle
, at this point the compiler will use static dispatch, which means that it would be recognizable which method should be called (Vehicle().Stop
or Car().Stop
) during the compile time. It selects the default implementation for Vehicle
which is implemented in the extension, without the need of checking what is the concrete type.
In case of:
let myCar = Car()
myCar.Drive()
myCar.Stop()
nothing special goes here, it works exactly as expected. That's exactly the the meaning of dynamic dispatch, which leads to apply polymorphic operations during the run time.
To make it more clear, consider that you have another type that conforms to Vehicle
protocol:
struct Bus: Vehicle {
func Drive() {
print("Bus Drive")
}
func Stop() {
print("Bus stop")
}
}
let myBus = Bus()
myCar.Drive()
myCar.Stop()
Obviously, the print("Bus stop")
is the one which will be called, and actually that's the expected! The compiler is "smart" enough to recognize which method to be selected based on what is the concrete type (Bus().Stop
).
Furthermore:
For better understanding of what's going on here, reviewing Understanding Swift Performance Apple session might be helpful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With