Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
2-1238999216
Дмитрий
2009-04-06 10:26
2009.05.24
Помогите обработать HResult


2-1238941348
Дмитрий
2009-04-05 18:22
2009.05.24
Помогите понять код на си


2-1239264269
JJ
2009-04-09 12:04
2009.05.24
Подключение к БД *.mdf


15-1237738703
Тимохов
2009-03-22 19:18
2009.05.24
Пролейте свет, знатоки, PHP5 + MySQL+Apache.


2-1239643253
VoznikVopros
2009-04-13 21:20
2009.05.24
Как изменить заголовок окна при вызове ShowMessage()?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский