Делает ли вызов Delphi унаследованным в переопределенных процедурах, если нет явного вызова - PullRequest
7 голосов
/ 10 сентября 2008

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

TForm >> TBaseForm >> TAnyOtherForm

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

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

Кроме того, если это вызов, унаследованный для меня, когда он будет вызывать его?

Ответы [ 7 ]

17 голосов
/ 10 сентября 2008

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

3 голосов
/ 10 сентября 2008

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

3 голосов
/ 10 сентября 2008

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

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

Возможно, вы могли бы переопределить 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;
2 голосов
/ 12 сентября 2008

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

1 голос
/ 12 сентября 2008

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

procedure TMyCalcObject.SolveForX;
begin
  ResetCalcState;
  inherited SolveForX;
  PostProcessSolveForX;
end;
0 голосов
/ 25 сентября 2013

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

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

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

0 голосов
/ 12 сентября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...