Да, есть разница, но давайте рассмотрим ключевое слово virtual
в более простых терминах ООП, но все же, как это относится к методам Delphi.
Когда вы объявляете производный (дочерний) класс и реализуете метод как «переопределить», это означает, что вы переопределяете (удивляете) метод сопоставления базового класса.
Это означает, что вы можете написать код так:
var child : TBaseClass;
begin
child := TChildClass.Create; // note that it is stored in TBaseClass variable
child.VirtualMethodDefinedInBaseClassThatHasBeenOverriddenInChildClass;
Это будет вызывать метод в дочернем классе, даже если переменная определена как типа базового класса. В этом и заключается цель виртуальных методов, вы можете получить доступ к объекту посредством ссылки более общего типа и по-прежнему вызывать методы, которые были написаны для определенного типа объекта, с которым вы имеете дело.
Если у вас есть виртуальный метод в базовом классе, который вы решили не переопределять в дочернем классе, но вместо этого повторно введете, вы в какой-то мере замените его. Обратите внимание, что в большинстве случаев вам нужно сообщить компилятору, что вы действительно хотели это сделать, хотя я не уверен, что здесь требуется Delphi.
В принципе, если ваша переменная имеет тип TBaseClass и вы вызываете на ней виртуальный метод, который был повторно введен в TChildClass, он все равно вызовет метод в базовом классе.
Однако, если ваша переменная имеет тип TChildClass, и вы вызываете этот метод на нее, вместо этого вы получите новый метод.
Теперь, для конструкторов, в Delphi, это немного отличается.
Точка виртуальных конструкторов должна иметь возможность практически строить объекты, и для этого в Delphi также есть «типы классов».
Вы можете сказать следующее:
type TClassToUse = class of TBaseClass;
var cls : TClassToUse;
obj : TBaseClass;
begin
cls := TChildClass;
obj := cls.Create;
(обратите внимание, что мое знание Delphi немного ржавое здесь, если кто-то видит ошибку или вопиющие проблемы в коде выше, пожалуйста, дайте мне знать, или просто исправить)
Здесь мы храним «класс» в переменной, а затем попросим класс запросить конструкцию объекта для нас. Это позволяет нам отключить класс для создания, но нам также нужно объявить конструкторы, которые мы хотим использовать виртуальными, иначе у нас будут проблемы.
Таким образом, в приведенном выше коде, если вы объявили конструктор виртуальным в TBaseClass, а затем переопределите его в TChildClass (который фактически использует код в cls
), переопределенный конструктор является тем, который будет использоваться.
Если, с другой стороны, вы не объявляете конструктор виртуальным, мы возвращаемся к конструктору базового класса. Виртуальный в основном означает вычисление правильного метода для выполнения во время выполнения, тогда как не виртуальный будет определять его во время компиляции.
Реинтродукция, как описано выше для нормальных методов, также работает таким образом.
Однако виртуальные конструкторы используются только как виртуальные при использовании по типу класса.
ли это Q имеет ничего общего с конструкторами, в частности, или с ООП в целом? –
на самом деле, просто хочу знать разницу, определенную в этом примере delphi. –
Было бы лучше, если бы вы не оставили угадывать игры в вопросе. Строки «// declare» - это часть базового класса или дочернего класса? Было бы лучше, если бы вы произвели полные, но минимальные примеры в каждом случае. –