You probably called the method with a variable of type Parent
.
Since method overloads are resolved at compile time, the compiler can only select an overload based on the static compile-time types of the parameters.
Therefore, even though your variable might actually contain a SubOfParent
instance at runtime, the compiler doesn't know that and will therefore choose the first overload.
Virtual methods, by contrast, are resolved at runtime based on the actual type of the instance involved.
Therefore, had SubOfParent
overridden a virtual method, calling that method on a variable of type Parent
would correctly call the overridden method if the instance is in fact of type SubOfParent
.