Это называется "динамический полиморфизм".
Виртуальные методы полезны тем, что вызывая метод через ссылку или указатель на базовый класс, на самом деле вы вызываете метод дочернего класса:
class B {
public:
virtual void f() {}
...
}
class D: public B{
public:
void f(){}
...
}
...
doF(D());
...
void doF(const B& b){
b.f();// вызовется D::f()
}
Если написать вместо тела виртуальной функции "=0;", то получится чисто виртуальный класс. Это уже полноценный аналог абстрактного класса в джаве. А если сделать все методы чисто виртуальными и не делать полей-данных, то получится аналог интерфейса.
Виртуальным обязательно должен быть деструктор у класса, который создаётся для наследования. Иначе сделав так:
B *d = new D();
delete d;
вы вызовете только деструктор базового класса.