Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проверка существования метода потомков в родителе, для форм это возможно? 
:(
    Опции темы
Bose
  Дата 27.10.2005, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 23
Всего: 51




Надо в форме-родителе вызвать метод который будет реализован в некоторых формах-наследниках(не во всех). Т.е. сначала надо проверить, существует ли этот метод в наследнике и, если существует, то вызвать его.

Класс-родитель:
Код

  TcsForm = class(TForm)
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  ...
  published
      procedure RefreshData; virtual; abstract;
  end;

procedure TcsForm.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
     if Key=VK_F5 then
     begin
          if TcsForm(Sender).MethodAddress(RefreshData)<>nil then Caption:='ok' else Caption:='Sux';
     end;
end;

сейчас получается, что проверка TcsForm(Sender).MethodAddress(RefreshData)<>nil всегда даёт True smile
PM MAIL WWW Skype   Вверх
maxim1000
Дата 27.10.2005, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 4
Всего: 110



уже не помню, как с этим в Delphi, но вообще, abstract приводит к тому, что если его не переопределить, то даже объект создать такой нельзя - компилятор не позволит...


--------------------
qqq
PM WWW   Вверх
Bose
Дата 27.10.2005, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 23
Всего: 51



хммм.... у меня создается... почему-то smile
но не суть... мне все-равно, будет там abstract или нет... около 40 форм уже сделано. и где-то примерно в 20 реализован метод RefreshData. И нужно сделать так, чтобы этот метод вызывался по нажатию на F5.
Я заменил предка для всех форм с TForm на свою TcsForm (Search & Replace). И в TcsForm пытаюсь проверить, реализован ли этот метод в той форме из которой пришло событие OneKeyDown...
PM MAIL WWW Skype   Вверх
maxim1000
Дата 27.10.2005, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 4
Всего: 110



ну тогда можно сделать так:
1. делаем в предке переменную (на всякий случай в private, чтобы никто из потомков не изменил)
2. реализовываем в предке эту функцию и пишем туда flag:=false, больше она ничего не делает

перед вызовом делаем flag:=true
вызываем функцию
проверяем flag


--------------------
qqq
PM WWW   Вверх
Bose
Дата 27.10.2005, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 23
Всего: 51



но тогда я не смогу вызвать одноименный метод, реализованный в потомке smile
т.е. каждый раз, когда я буду вызывать этот метод в предке, у меня будет вызываться метод, который только и умеет, что изменять флаг smile
PM MAIL WWW Skype   Вверх
maxim1000
Дата 27.10.2005, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 4
Всего: 110



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

нет, в этом и весь смысл виртуальности
если в предке реализован какой-то виртуальный метод, а в потомке переопределен, то даже из предка будет вызываться метод потомка...


--------------------
qqq
PM WWW   Вверх
Bose
Дата 27.10.2005, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 23
Всего: 51



получилось!
Спасибо, maxim1000!
Я до сих пор не могу осмыслить всей гибкости предостовляемой ОбьектноОриентированным Программированием, и черезвычайно радуюсь, когда удается узнать новый прием. smile

В общем я сделал так:

в предке создал пустой виртуальный метод RefreshData
Код

TcsForm = class(TForm)    
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);    
  ...    
  published    
      procedure RefreshData; virtual; 
  end;    

procedure TcsForm.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);    
begin    
     if Key=VK_F5 then    RefreshData;
end;

procedure TcsForm.RefreshData;
begin
     //void
end;


а ко всем обьявлениям RefreshData в потомках, добавил директиву override; (заработало все только после добавления override)

только я все-равно не понимаю, почему оно не работало, без override. как я себе представлял, override же должен был прятать метод TcsForm.RefreshData, что мне совсем не должно было мешать... А на деле оказалось совсем наоборот... smile
PM MAIL WWW Skype   Вверх
<Spawn>
Дата 27.10.2005, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Око кары:)
****


Профиль
Группа: Экс. модератор
Сообщений: 2776
Регистрация: 29.1.2003
Где: Екатеринбург

Репутация: 44
Всего: 64



Это можно запросто реализовать через интерфейсы:

Код

//Базовый класс
TMyClass = class(TObject)
end;

//Интерфейс 
//GUID в данном случае не обязателен
IMyInterface = interface(IInterface)
  procedure HelloWorld;
end;

//Класс, реализующий методы интерфейса IMyInterface
TMyClass2 = class(TMyClass, IMyInterface)
  procedure HelloWorld;
end;

TMyClass2 = class(TMyClass)
//Какие то методы класса
end;

var
  MyClassInstance: TMyClass;

//Где то в программе инициализируется указатель на экзмепляр класса MyClassInstance, тогда для определения доступености метода используем наш интерфейс

if MyClassInstance is IMyInterface then
  (MyClassInstance as IMyInterface).HelloWorld;



--------------------
"Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков.
PM MAIL ICQ   Вверх
<Spawn>
Дата 27.10.2005, 15:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Око кары:)
****


Профиль
Группа: Экс. модератор
Сообщений: 2776
Регистрация: 29.1.2003
Где: Екатеринбург

Репутация: 44
Всего: 64



Цитата(Bose @ 27.10.2005, 17:19)
только я все-равно не понимаю, почему оно не работало, без override. как я себе представлял, override же должен был прятать метод TcsForm.RefreshData, что мне совсем не должно было мешать... А на деле оказалось совсем наоборот... smile

override ни чего не прячет! Он указывает компилятору создать нужные связи в VMT(Virtual Method Table, если не ошибаюсь) таблице для того, чтобы методы экземпляра класса наследника можно было вызвать из переменной класса предка. Т.е.:

Код

TMyClass = class
  procedure Hi; virtual;
end;

procedure TMyClass.Hi;
begin
  ShowMessage('hi');
end;

TMyClass2=class(TMyClass)
  procedure Hi; override;
end;

procedure TMyClass2.Hi;
begin
  inherited;
  ShowMesage('Hi from TMyClass2 instance');
end;

TMyClass3 = class(TMyClass)
  procedure Hi; 
end;

procedure TMyClass3.Hi;
begin
  ShowMessage('blabalbla');
end;

var
  MyClassInstance: TMyClass;
begin
  //При использовании переопределенного виртуального метода (через директиву override)
  //ты должен будешь увидеть 2 сообщения(предка и наследкника. Сообщение предка вызывается из зи включения его кода директивой inherited)
  MyClassInstance := TMyClass2.Create;  
  MyClassInstance.Hi;
  ...
  //В данном же случае ты увидишь только вызов метода предка
  MyClassInstance := TMyClass3.Create;  
  MyClassInstance.Hi;
end;



--------------------
"Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков.
PM MAIL ICQ   Вверх
Bose
Дата 27.10.2005, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 23
Всего: 51



<Spawn>
Я имел в виду, что вот здесь:
Код

//В данном же случае ты увидишь только вызов метода предка    
  MyClassInstance := TMyClass3.Create;    
  MyClassInstance.Hi;

с моей точки зрения должен был бы сработать TMyClass3.Hi; а не TMyClass.Hi, а применение директивы override при обьявлении TMyClass3.Hi, позволило бы вызвать TMyClass.Hi из TMyClass3.Hi.
Короче, я ошибался. =)

p.s. Вот такие вот подробные обьяснения, было бы неплохо включать в FAQ Vingrad'a... smile
PM MAIL WWW Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0939 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.