![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Определить наличие процедуры [D7, XP]
Roman88 © (2009-04-06 14:33:00)Здравствуйте. Подскажите, если не сложно.
Пишу приложение где есть форма от которой наследуются куча других форм.
У базовой формы есть процедура, которую вызывают все наследники в событии OnShow. Выпала задача, в этой процедуре базовой формы определить существует ли процедура например SetButtonsOff у вызывающего наследника. Как можно программно узнать существует ли процедура, что бы можно было ее вызвать ?
Процедуры у наследников объявлены в
public
procedure SetButtonsOff ; override;
AndreyV (2009-04-06 16:16:00) [1]> [21] Roman88 (06.04.09 15:27)
А нафига предку знать о потомках? Что там у них перекрыто - ему должно быть фиолетого.
Сергей М. (2009-04-06 15:28:00) [2]
> Сделал как в [19]
Ну и совершенно неразумно поступил.
Roman88 (2009-04-06 15:27:00) [3]Всем огромное спасибо!!! Очень помогли. Сделал как в [19] , все работает отлично.
Ega23 (2009-04-06 15:15:00) [4]
> нужно лишь узнать есть ли в списке Public наследника тот
> или иной метод.
Если он объявлен у предка в public как виртуальный, то он естьв наследнике.
Если он перекрыт в наследнике ( override), то будет вызван метод наследника. Если внутри этого метода где-то стоит inherited, то в этом месте будет вызван код предка. Если inherited нет, то код предка вызван не будет.
Если он в наследнике не перекрыт, то будет вызван просто код предка.
Сергей М. (2009-04-06 15:14:00) [5]
> нужно лишь узнать есть ли в списке Public наследника тот
> или иной метод
Если ты перенесешь объявление из секции Public в секцию Published, то задача решается в оlну строчку:
if Descendant.MethodAddress('SetButtonsOff') <> nil then объявлен else не объявлен
Roman88 (2009-04-06 15:09:00) [6]
> Насколько я понимаю, это не то, что тебе надо. Это то, что
> поможет тебе разобраться, что такое наследование и полиморфизм.
>
>
ясно, сейчас попробую разобраться ...
Roman88 (2009-04-06 15:08:00) [7]насколько я понял, здесь можно получить список объявленных методов только если они будут вызваны. У меня вызов метода не происходит, нужно лишь узнать есть ли в списке Public наследника тот или иной метод.
Ega23 (2009-04-06 15:05:00) [8]
> Кажется то, что надо, спасибо :)
Насколько я понимаю, это не то, что тебе надо. Это то, что поможет тебе разобраться, что такое наследование и полиморфизм.
Roman88 (2009-04-06 15:04:00) [9]
> Ega23 © (06.04.09 14:59) [13]
Кажется то, что надо, спасибо :)
Ega23 (2009-04-06 15:01:00) [10]Разберись с этим кодом. Многое станет понятно.
Ega23 (2009-04-06 14:59:00) [11]
unit Unit3;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Contnrs, StdCtrls;
type
TAncestorClass = class (TObject)
public
procedure Method1; virtual;
procedure Method2; virtual;
end;
TFirstChild = class (TAncestorClass)
public
procedure Method1; override;
end;
TSecondChild = class (TAncestorClass)
public
procedure Method2; override;
end;
TMyList = class (TObjectList)
private
function GetItem(Index: Integer): TAncestorClass;
public
property Items[Index : Integer] : TAncestorClass read GetItem;
end;
TForm3 = class(TForm)
btnAddFirstChild: TButton;
btnAddSecondChild: TButton;
btnRunMethod1: TButton;
btnRunMethod2: TButton;
btnClearList: TButton;
procedure btnAddFirstChildClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure btnAddSecondChildClick(Sender: TObject);
procedure btnClearListClick(Sender: TObject);
procedure btnRunMethod1Click(Sender: TObject);
procedure btnRunMethod2Click(Sender: TObject);
private
List : TMyList;
public
{ Public declarations }
end;
var
Form3: TForm3;
implementation
{$R *.dfm}
{ TAncestorClass }
procedure TAncestorClass.Method1;
begin
ShowMessage('TAncestorClass.Method1;');
end;
procedure TAncestorClass.Method2;
begin
ShowMessage('TAncestorClass.Method2;');
end;
{ TFirstChild }
procedure TFirstChild.Method1;
begin
inherited;
ShowMessage('TFirstChild.Method1;');
end;
{ TSecondChild }
procedure TSecondChild.Method2;
begin
inherited;
ShowMessage('TSecondChild.Method2;');
end;
{ TMyList }
function TMyList.GetItem(Index: Integer): TAncestorClass;
begin
Result := (inherited GetItem(Index)) as TAncestorClass;
end;
procedure TForm3.btnAddFirstChildClick(Sender: TObject);
begin
List.Add(TFirstChild.Create);
end;
procedure TForm3.btnAddSecondChildClick(Sender: TObject);
begin
List.Add(TSecondChild.Create);
end;
procedure TForm3.btnClearListClick(Sender: TObject);
begin
List.Clear;
end;
procedure TForm3.btnRunMethod1Click(Sender: TObject);
var
i : Integer;
begin
for i:=0 to List.Count-1 do
List.Items[i].Method1;
end;
procedure TForm3.btnRunMethod2Click(Sender: TObject);
var
i : Integer;
begin
for i:=0 to List.Count-1 do
List.Items[i].Method2;
end;
procedure TForm3.FormCreate(Sender: TObject);
begin
List := TMyList.Create;
end;
procedure TForm3.FormDestroy(Sender: TObject);
begin
List.Free;
end;
end.
Сергей М. (2009-04-06 14:56:00) [12]Если у наследника метод не объявлен (т.е. наследник не перекрыл метод предка), то его вызов откуда бы то ни было приведет к вызову одноименного виртуального метода предка.
Roman88 (2009-04-06 14:50:00) [13]Я чайник в ООП, но у наследников в паблик объявляю только необходимые для формы процедуры.
public
procedure SetButtonsOff ; override;
end;
Сергей М. (2009-04-06 14:49:00) [14]Предок просто должен вызвать свойвиртуальный метод.
Если он перекрыт у наследника, то вместо метода предка быдет вызыван перекрытый метод наследника.
Ega23 (2009-04-06 14:47:00) [15]
> У предка есть 20 процедур, а у наследников могут быть объявлены
> только несколько. Так вот мне нужно знать какие именно объявлены
> у наследника, программным путем.
>
У наследника "объявлены" тоже 20. Другое дело, что может быть перекрытотолько несколько. Но это не значит, что у потомка их нет.
Roman88 (2009-04-06 14:46:00) [16]У предка есть 20 процедур, а у наследников могут быть объявлены только несколько. Так вот мне нужно знать какие именно объявлены у наследника, программным путем.
Ega23 (2009-04-06 14:46:00) [17]
> У базового он м.б. абстрактным
Может. Но он один фиг есть. другое дело, что abstract error получишь.
Сергей М. (2009-04-06 14:44:00) [18]
> Процедуры у наследников объявлены
Раз объявлены, значит существуют. И проверять ничего не надо.
Roman88 (2009-04-06 14:43:00) [19]
> А у предка как объявлен этот метод ?
public
procedure SetButtonsOff;virtual; // Метод для меню "Сохранить..."
Roman88 (2009-04-06 14:42:00) [20]Пытался получить таким образом:
if Assigned(self.SetButtonsOff) then;
Компилятор дает ошибку:
[DCC Error] uRegisterClasses.pas(658): E2036 Variable required