The C# team did not like adding optional arguments to the language, this is a rather good demonstration why.
It helps to understand how they are implemented. The CLR is quite oblivious of the feature, it is implemented by the compiler. If you write a method call with a missing argument then the C# compiler actually generates the code for the method call with an argument, passing the default value. Easy to see with ildasm.exe.
You can see this back in the language rules, the optional value must be a constant expression. Or in other words, a value that can be determined at compile time. You cannot use the new keyword or an expression that uses variables. Required so the compiler can embed the default value in the assembly metadata. It will need it again when it compiles a call to a method with optional arguments that's declared in another assembly.
The friction here is that the compiler cannot figure out which virtual method is actually going to be called at runtime. Dynamic dispatch is a pure runtime feature.
So all it reasonably can go by is the declared type of the object reference. You used all three versions so you get all three default argument values.