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

StackOverflow https://stackoverflow.com/questions/53715

  •  09-06-2019
  •  | 
  •  

Вопрос

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

TForm >> TBaseForm >> TAnyOtherForm

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

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

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

Это было полезно?

Решение

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

Другие советы

Стоит отметить, что отказ от вызова inherited в 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», сообщающая компилятору, что вы не хотите вызывать унаследованный метод.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top