Вызов Delphi наследуется при переопределенных процедурах, если нет явного вызова

вызывает ли Delphi унаследованный на переопределенных процедурах, если нет явного вызова в коде ie (унаследованный;), у меня есть следующая структура (от супер до подкласса)

TForm > > TBaseForm >> TAnyOtherForm

все формы в проекте будут получены из TBaseForm, так как это будет иметь все стандартные настройки и разрушительные части, которые используются для каждой формы (безопасность, проверка ect).

TBaseForm имеет процедуры onCreate и onDestroy с кодом для этого, но если кто-то (то есть я) забыл добавить унаследованное в onCreate на TAnyOtherForm, Delphi назовет его для меня? Я нашел ссылки в интернете, которые говорят, что это не требуется, но нигде не говорится, вызывается ли он, если он опущен из кода.

также, если он вызывает унаследованный для меня, когда он его вызовет?

7 ответов


нет, если вы оставите вызов унаследованным, он не будет вызван. В противном случае было бы невозможно переопределить метод и полностью ommit его родительскую версию.


стоит отметить, что не вызов унаследованного в Destroy любого объекта может привести к утечкам памяти. Есть инструменты, доступные для проверки этого в исходном коде.


наследуемый вызов должен быть выполнен явно. Как правило, ни один язык автоматически не вызывает унаследованную функцию в эквивалентных ситуациях (конструкторы классов не включены).

легко забыть сделать унаследованный вызов в конструкторе класса. В такой ситуации если базовый класс должен инициализировать все данные у вас есть нарушение прав доступа замедленного действия.

возможно, вы могли бы переопределить DoCreate и DoDestory в своем классе TBaseForm, чтобы обеспечить некоторый код выполняется независимо от реализации дочерних классов.

// interface

TBaseForm = Class(TForm)
...
Protected
    Procedure DoCreate(Sender : TObject); Override;
End

// implementation

Procedure TBaseForm.DoCreate(Sender : TObject);
Begin
    // do work here

    // let parent call the OnCreate property  
    Inherited DoCreate(Sender);
End;

Inherited должен быть явно вызван в объектах-потомках, а также в наследовании визуальной формы. Если вы используете завершение класса, он автоматически добавляет унаследованное, если вы отметили определение как переопределение (но не для повторного введения). Если вы используете наследование визуальной формы, то при добавлении нового события через редактор форм он также добавит унаследованное.


унаследованный код не вызывается неявно, как другие указали. Вы должны вызвать его явно. Это дает вам некоторую полезную гибкость. Например, может потребоваться выполнить некоторую предварительную обработку кода до унаследованного кода,а затем выполнить код после обработки. Это может выглядеть так:

procedure TMyCalcObject.SolveForX;
begin
  ResetCalcState;
  inherited SolveForX;
  PostProcessSolveForX;
end;

нет. В этом весь смысл переопределения.


вы должны вызвать его явно. Это обеспечивает большую гибкость, так как вы можете выбрать, в какой момент кода вызывать унаследованный метод. Но это также большой источник ошибок. Легко забыть вызвать унаследованную функцию, и компилятор не может сказать, сделали ли вы это намеренно или просто забыли.

должна быть какая-то директива "skip_inherited", чтобы сообщить компилятору, что вы не хотите вызывать унаследованный метод.

компилятор будет легко сообщите об ошибке, если он не нашел "унаследованный" или "skip_inherited". Это значит, что ты забыл. Но, к сожалению, никто в CodeGear не подумал об этом.