В С++ я должен явно указать "виртуальное" ключевое слово, чтобы сделать функцию члена "overridable", поскольку в ней возникают накладные расходы на создание виртуальных таблиц и vpointers, когда функция-член становится переопределяемой (поэтому каждая функция-член неявно не зависящие по производительности).
Он также позволяет скрывать функцию-член (если не переопределять), когда подкласс предоставляет отдельную реализацию с тем же именем и сигнатурой.
Тот же метод используется и на С#. Мне интересно, почему Java отмахивалась от этого поведения и делала каждый метод переопределяемым по умолчанию и предоставляла возможность отключать переопределение поведения при явном использовании ключевого слова final.