![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вызов метода предка класса минуя непосредственного предка. [D5, Win2k]
harisma © (2006-08-17 14:03:00)Вопрос такой: Есть 3 класса А - В - С. В унаследован от А, С унаследован от В. В классах есть перекрытый метод. Как мне из этого метода в классе С вызвать этот же метод класса А? типа как делается inherited для вызова метода непосредственного предка?
default (2006-08-18 11:24:00) [1]WondeRu © (17.08.06 15:08) [27]
так делать в общем случае нельзя
вызывать надо процедуру объекта, а не обычную
в данном случае просто повезло, что работает
default (2006-08-18 11:22:00) [2]tesseract © (18.08.06 10:45) [28]
я ни в коем случае ни на кого не намекал говоря про крутость!
просто указал, что стоит задуматься автору сабжа над архитектурой класса прежде чем использовать выданные решения
подобные решения скорее как задачка для какого-нибудь собеседования, чем на реальное применение
tesseract (2006-08-18 10:45:00) [3]
> default © (17.08.06 15:03) [26]
Я никогда свою крутость не показывал. Имхо как раз перезаписывание VMT - ошибка проектирования. Чистое ИМХО.
WondeRu (2006-08-17 15:08:00) [4]вот в своем проекте нашел:
иерархия такая
A-B-C
type
TDrawProj = procedure (Sender: TObject; const SelectRender: Boolean = False);
.....
procedure C.Draw(const SelectRender: Boolean = False);
begin
TDrawProj(@A.Draw)(Self, SelectRender);
....
end;
default (2006-08-17 15:03:00) [5]важно понять, что эти "финты" всего лишь заплаты для огрех проектирования
(скорее всего)
свою "крутость" в них показывать на самом деле не круто
default (2006-08-17 14:57:00) [6]непосредственного предка
default (2006-08-17 14:56:00) [7]во всех(думаю нет ислючений) ООП языках, есть специальный синтаксис только для вызова метода предка
стоит задумать о архитектуре классов, прежде чем городить огород из подобных "финтов" - максимум простоты и логичности!
default (2006-08-17 14:47:00) [8]harisma (17.08.06 14:44) [20]
дали уже два решения [5] и [18]
tesseract © (17.08.06 14:44) [22]
[20]
tesseract (2006-08-17 14:44:00) [9]
> default © (17.08.06 14:42) [19]
насчёт этого я как раз в курсе, а что это не решение [0] ?
begin...end (2006-08-17 14:44:00) [10]В [18] P -- это имя метода, конечно.
harisma (2006-08-17 14:44:00) [11]У меня этот метод объявлен как virtual только в классе А. В классах В и С он обїявляется как override.
default (2006-08-17 14:42:00) [12]tesseract © (17.08.06 14:37) [17]
блин, траблы у тебя с объектной моделью...
ты везде virtual пишешь - это значит новый метод, а не перекрытие старого...
тогда, конечно, приведение будет работать...
begin...end (2006-08-17 14:39:00) [13]Пример к [6]:
var
ObjC: C;
TempClass: TClass;
begin
...
TempClass := ObjC.ClassType;
try
PPointer(ObjC)^ := ObjC.ClassParent.ClassParent;
ObjC.P;
finally
PPointer(ObjC)^ := TempClass;
end;
...
end
tesseract (2006-08-17 14:37:00) [14]
procedure Tclass3.ShowMessage;
begin
Tclass1(self).ShowMessage;
inherited ShowMessage;
MessageBox(0, 'class 3', ' no error', MB_ICONWARNING or MB_OK);
end;
так нагляднее, в D7 работает.
tesseract (2006-08-17 14:36:00) [15]
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type Tclass1= class
public
procedure ShowMessage; virtual;
end;
type Tclass2= class(Tclass1)
public
procedure ShowMessage; virtual;
end;
type Tclass3= class(Tclass2)
public
procedure ShowMessage; virtual;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ Tclass1 }
procedure Tclass1.ShowMessage;
begin
MessageBox(0, 'class 1', ' no error', MB_ICONWARNING or MB_OK);
end;
procedure Tclass2.ShowMessage;
begin
MessageBox(0, 'class 2', ' no error', MB_ICONWARNING or MB_OK);
end;
procedure Tclass3.ShowMessage;
begin
Tclass1(self).ShowMessage;
end;
procedure TForm1.Button1Click(Sender: TObject);
var c1: Tclass1;
c2: Tclass2;
c3: Tclass3;
begin
c1:=tclass1.Create;
c2:=tclass2.Create;
c3:=tclass3.Create;
c3.ShowMessage;
c1.Free;
c2.Free;
c3.Free;
end;
end.
Вроде работает, но как там с полями/другими методами будет не уверен.
Ketmar (2006-08-17 14:34:00) [16]> [13] default © (17.08.06 14:27)
пардон, не вчитался. снова извиняюсь.
что-то я сегодня слова теряю...
begin...end (2006-08-17 14:31:00) [17]> Ketmar © (17.08.06 14:24) [9]
Смело...
default (2006-08-17 14:27:00) [18]tesseract © (17.08.06 14:26) [12]
такой способ прокатит только для статических методов
с виртуальными такое не прокатит
tesseract (2006-08-17 14:26:00) [19]
> default © (17.08.06 14:22) [7]
Почему? Ведь должен вызваться метод родителя, а не потомка.
default (2006-08-17 14:25:00) [20][3] то есть...