Форум: "Начинающим";
Текущий архив: 2009.05.24;
Скачать: [xml.tar.bz2];
Вниз
Определить наличие процедуры Найти похожие ветки
← →
Roman88 (2009-04-06 14:33) [0]Здравствуйте. Подскажите, если не сложно.
Пишу приложение где есть форма от которой наследуются куча других форм.
У базовой формы есть процедура, которую вызывают все наследники в событии OnShow. Выпала задача, в этой процедуре базовой формы определить существует ли процедура например SetButtonsOff у вызывающего наследника. Как можно программно узнать существует ли процедура, что бы можно было ее вызвать ?
Процедуры у наследников объявлены в
public
procedure SetButtonsOff ; override;
← →
Ega23 © (2009-04-06 14:38) [1]Если она override, то она полюбому есть. Если нет реализации в конкретном потомке, значит она у базового класса.
← →
Сергей М. © (2009-04-06 14:40) [2]А у предка как объявлен этот метод ?
← →
Сергей М. © (2009-04-06 14:41) [3]
> значит она у базового класса
У базового он м.б. абстрактным
← →
Roman88 (2009-04-06 14:42) [4]Пытался получить таким образом:
if Assigned(self.SetButtonsOff) then;
Компилятор дает ошибку:
[DCC Error] uRegisterClasses.pas(658): E2036 Variable required
← →
Roman88 (2009-04-06 14:43) [5]
> А у предка как объявлен этот метод ?
public
procedure SetButtonsOff;virtual; // Метод для меню "Сохранить..."
← →
Сергей М. © (2009-04-06 14:44) [6]
> Процедуры у наследников объявлены
Раз объявлены, значит существуют. И проверять ничего не надо.
← →
Ega23 © (2009-04-06 14:46) [7]
> У базового он м.б. абстрактным
Может. Но он один фиг есть. другое дело, что abstract error получишь.
← →
Roman88 (2009-04-06 14:46) [8]У предка есть 20 процедур, а у наследников могут быть объявлены только несколько. Так вот мне нужно знать какие именно объявлены у наследника, программным путем.
← →
Ega23 © (2009-04-06 14:47) [9]
> У предка есть 20 процедур, а у наследников могут быть объявлены
> только несколько. Так вот мне нужно знать какие именно объявлены
> у наследника, программным путем.
>
У наследника "объявлены" тоже 20. Другое дело, что может быть перекрыто только несколько. Но это не значит, что у потомка их нет.
← →
Сергей М. © (2009-04-06 14:49) [10]Предок просто должен вызвать свой виртуальный метод.
Если он перекрыт у наследника, то вместо метода предка быдет вызыван перекрытый метод наследника.
← →
Roman88 (2009-04-06 14:50) [11]Я чайник в ООП, но у наследников в паблик объявляю только необходимые для формы процедуры.
public
procedure SetButtonsOff ; override;
end;
← →
Сергей М. © (2009-04-06 14:56) [12]Если у наследника метод не объявлен (т.е. наследник не перекрыл метод предка), то его вызов откуда бы то ни было приведет к вызову одноименного виртуального метода предка.
← →
Ega23 © (2009-04-06 14:59) [13]
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.
← →
Ega23 © (2009-04-06 15:01) [14]Разберись с этим кодом. Многое станет понятно.
← →
Roman88 (2009-04-06 15:04) [15]
> Ega23 © (06.04.09 14:59) [13]
Кажется то, что надо, спасибо :)
← →
Ega23 © (2009-04-06 15:05) [16]
> Кажется то, что надо, спасибо :)
Насколько я понимаю, это не то, что тебе надо. Это то, что поможет тебе разобраться, что такое наследование и полиморфизм.
← →
Roman88 (2009-04-06 15:08) [17]насколько я понял, здесь можно получить список объявленных методов только если они будут вызваны. У меня вызов метода не происходит, нужно лишь узнать есть ли в списке Public наследника тот или иной метод.
← →
Roman88 (2009-04-06 15:09) [18]
> Насколько я понимаю, это не то, что тебе надо. Это то, что
> поможет тебе разобраться, что такое наследование и полиморфизм.
>
>
ясно, сейчас попробую разобраться ...
← →
Сергей М. © (2009-04-06 15:14) [19]
> нужно лишь узнать есть ли в списке Public наследника тот
> или иной метод
Если ты перенесешь объявление из секции Public в секцию Published, то задача решается в оlну строчку:
if Descendant.MethodAddress("SetButtonsOff") <> nil then объявлен else не объявлен
← →
Ega23 © (2009-04-06 15:15) [20]
> нужно лишь узнать есть ли в списке Public наследника тот
> или иной метод.
Если он объявлен у предка в public как виртуальный, то он есть в наследнике.
Если он перекрыт в наследнике (override), то будет вызван метод наследника. Если внутри этого метода где-то стоит inherited, то в этом месте будет вызван код предка. Если inherited нет, то код предка вызван не будет.
Если он в наследнике не перекрыт, то будет вызван просто код предка.
← →
Roman88 (2009-04-06 15:27) [21]Всем огромное спасибо!!! Очень помогли. Сделал как в [19] , все работает отлично.
← →
Сергей М. © (2009-04-06 15:28) [22]
> Сделал как в [19]
Ну и совершенно неразумно поступил.
← →
AndreyV © (2009-04-06 16:16) [23]> [21] Roman88 (06.04.09 15:27)
А нафига предку знать о потомках? Что там у них перекрыто - ему должно быть фиолетого.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2009.05.24;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.006 c