Необходимость в том, что производные классы могут переопределять, и они ведут себя так, как вы ожидаете.
Обратное происходит при создании метода в производном классе с указанием ключевого слова new - в этой ситуации используется версия функции, которая соответствует типу переменной, поэтому:
derived foo = new derived();
base foo2 = foo;
foo2.bar(); // If bar() is virtual, and overriden in derived, it will use that implementation.
foo.bar(); // if bar() is not virtual, this may be calling a completely different function, if derived defines a new version