Виртуальный метод


Виртуальный метод (виртуальная функция) — в объектно-ориентированном программировании метод (функция) класса, который может быть переопределён в классах-наследниках так, что конкретная реализация метода для вызова будет определяться во время исполнения. Таким образом, программисту необязательно знать точный тип объекта для работы с ним через виртуальные методы: достаточно лишь знать, что объект принадлежит классу или наследнику класса, в котором объявлен метод. Одним из переводов слова virtual с английского языка может быть «фактический», что больше подходит по смыслу. [источник не указан 1291 день]

Виртуальные методы — один из важнейших приёмов реализации полиморфизма. Они позволяют создавать общий код, который может работать как с объектами базового класса, так и с объектами любого его класса-наследника. При этом базовый класс определяет способ работы с объектами, и любые его наследники могут предоставлять конкретную реализацию этого способа.

Одни языки программирования (например, C++, C#, Delphi) требуют явно указывать, что данный метод является виртуальным. В других языках (например, Java, Python) все методы являются виртуальными по умолчанию (но только те методы, для которых это возможно; например, в Java методы с доступом private не могут быть переопределены в связи с правилами видимости).

Базовый класс может и не предоставлять реализации виртуального метода, а только декларировать его существование. Такие методы без реализации называются «чистыми виртуальными» (перевод англ.  pure virtual) или абстрактными. Класс, содержащий хотя бы один такой метод, тоже будет абстрактным. Объект такого класса создать нельзя (в некоторых языках допускается, но вызов абстрактного метода приведёт к ошибке). Наследники абстрактного класса должны предоставить[1] реализацию для всех его абстрактных методов, иначе они, в свою очередь, будут абстрактными классами. Абстрактный класс, который содержит только абстрактные методы, называется интерфейсом.

Техника вызова виртуальных методов называется ещё «динамическим (поздним) связыванием». Имеется в виду, что имя метода, использованное в программе, связывается с адресом входа конкретного метода динамически (во время исполнения программы), а не статически (во время компиляции), так как в момент компиляции, в общем случае, невозможно определить, какая из существующих реализаций метода будет вызвана.