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

Вниз

Наследование методов   Найти похожие ветки 

 
nikolo ©   (2002-11-06 11:46) [0]

Всем привет! Проблема в следующем: создал форму и поместил ее в Repository. В этой форме объявил несколько методов, один из которых FormKeyDown. Так вот, создаю в проекте новую форму inherit от данной и объявляю в ней также FormKeyDown так:

procedure TfmEd.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
inherited;
if Key = VK_F4 then ShowMessage("Ok");
end;


Проблема - у наследника в этот метод прога вообще не заходит, выполняет код только у предка. Почему? Подскажите, что надо сделать.


 
SaS13 ©   (2002-11-06 12:17) [1]

подробности не помешают:
как объявлял (текст)? в каком разделе?


 
Skier ©   (2002-11-06 12:22) [2]

>nikolo
А событие привязываешь OnKeyDown := FormKeyDown ?


 
nikolo ©   (2002-11-06 12:32) [3]

В предке:

type
TfmEdit_ = class(TForm)
...
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
private { Private declarations }
public { Public declarations }
end;


В наследнике:

type
TfmEd = class(TfmEdit_)
...
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
private { Private declarations }
public { Public declarations }
end;

var
fmEd: TfmEd;

implementation

{$R *.DFM}

procedure TfmEd.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
inherited;
if Key = VK_F4 then ShowMessage("Ok");
end;


 
SaS13 ©   (2002-11-06 12:35) [4]

а с чего ты взял что FormKeyDown у тебя будет выполняться, ты его сам что-ли вызываешь?


 
Андрей Прокофьев ©   (2002-11-06 12:40) [5]

type
TfmEd = class(TfmEdit_)
...
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); override;
private { Private declarations }
public { Public declarations }
end


 
gek ©   (2002-11-06 12:42) [6]

override


 
Skier ©   (2002-11-06 12:43) [7]

>Андрей Прокофьев
А что FormKeyDown объявлен как virtual или dynamic ?!


 
SaS13 ©   (2002-11-06 12:47) [8]

to Nikolo
Проблема - у наследника в этот метод прога вообще не заходит, выполняет код только у предка.
ты сам его что-ли на OnKeyDown в предке вызываешь?


 
nikolo ©   (2002-11-06 12:54) [9]

Поставил override и все заработало, всем спасибо!

Может кому-нибудь не будет лень вкратце объяснить что такое override, virtual и dynamic и как они между собой связаны. Только, пожалуйста, не говорите о книжках, где об этом можно почитать, когда объясняют "на пальцах" это гораздо понятнее.
Буду очень благодарен!


 
gek ©   (2002-11-06 12:55) [10]


program kuku;

uses
Forms,
Unit1 in "Unit1.pas" {Form1},
Unit2 in "Unit2.pas" {Form2};

{$R *.RES}

begin
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Application.Run;
end.

//********************************************************
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses Unit2;

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.Show;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
MessageBeep (0);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
MessageBeep (0);
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
ShowMessage ("Hi");
end;

end.

//****************************************************************
unit Unit2;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Unit1, StdCtrls;

type
TForm2 = class(TForm1)
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form2: TForm2;

implementation

{$R *.DFM}

procedure TForm2.Button2Click(Sender: TObject);
begin
inherited;
ShowMessage ("Hi");
end;

procedure TForm2.Button3Click(Sender: TObject);
begin
ShowMessage ("Hi");
end;

procedure TForm2.Button4Click(Sender: TObject);
begin
inherited Button3Click (Sender);
inherited;
end;

end.




Это уж точнее некуда работает


 
nikolo ©   (2002-11-06 13:14) [11]

Ок, но здесь нет override, virtual или dynamic :(


 
AlexT1000   (2002-11-06 13:33) [12]

override - метод который полностью замещает методы с такими же именами предков
virtual - при вызове этого метода вызовутся все методы с таким же именем всех предков по очереди

чтобы из override метода вызвать метод предка нужно писать
в коде метода
inherited

что то в этом роде .


 
Бурундук   (2002-11-06 13:45) [13]

nikolo © (06.11.02 13:14)
На самом деле этот топик имеет малое отношение
к наследованию.
Обработчик события - феномен (не хочу употреблять "объект"
во избежание недоразумений) чисто статический,
т.е. в TMethod.Code лежит статический адрес метода,
и не важно, сам этот метод виртуальный или нет.

Все нюансы этого вопроса лежат в загрузке формы из дфм -
какой метод лежит в таблицах РТТИ под
именем "FormKeyDown" и
какая форма реально загружает в своё св-во OnKeyDown
метод с этим именем из своей таблицы РТТИ.

Играясь наследованием, можно влиять и на эти вещи, но
наследование здесь вторично.

Например, если виртуальный метод, объявленный
у предка в published, у потомка помещён в public,
то MethodAddress потомка даст адрес метода предка,
а если в published - то потомка.


 
nikolo ©   (2002-11-06 14:43) [14]

Кое-что стало понятно, спасибо


 
nikolo ©   (2002-11-06 17:53) [15]

> gek ©
Поковырял твой исходник, но что-то по всей видимости не то, может ты забыл как раз расставить virtual, override и т.д.?


 
oomneeq ©   (2002-11-06 19:29) [16]

>Андрей Прокофьев
А что FormKeyDown объявлен как virtual или dynamic ?!

По умолчанию коды обработчиков событий статические
Но можно сделать самому, приписав virtual к сгенеренному дельфей объявлению обработчика.
Неочевидный но факт.
Я вычитал у Marco Cantu про ето
http://www.ozon.ru/?context=detail&id=120134
стр 105



Страницы: 1 вся ветка

Текущий архив: 2002.11.18;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.03 c
4-59498
Василий2
2002-10-06 18:16
2002.11.18
Прошу оветить всех знающих...


14-59355
Driverrr
2002-10-18 18:50
2002.11.18
FORMAT C:


3-59002
Separator
2002-10-29 06:59
2002.11.18
Доступ к MySQL


8-59287
Yuri Btr
2002-07-29 11:55
2002.11.18
Вопрос по bass.dll


1-59273
chips
2002-11-06 10:36
2002.11.18
передача параметров приложению