Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Вызов метода предка класса минуя непосредственного предка. [D5, Win2k]


Страницы:   1 2

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] то есть...


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо