Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.05.24;
Скачать: CL | DM;

Вниз

Определить наличие процедуры   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.011 c
10-1157121608
MixAnOL
2006-09-01 18:40
2009.05.24
Как установить OLE объект из dll в delphi


2-1239007118
@!!ex
2009-04-06 12:38
2009.05.24
StringReplace не работает с длинными строками?


2-1239098915
AlexDan
2009-04-07 14:08
2009.05.24
ms sql и delphi


11-1201052252
Elec3C
2008-01-23 04:37
2009.05.24
Вопрос по IniFile (ValueString)


2-1239093371
Анфиса
2009-04-07 12:36
2009.05.24
Excel в Delphi