Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2011.09.25;
Скачать: [xml.tar.bz2];

Вниз

Вызов inherited определённого базового класса   Найти похожие ветки 

 
LightGreen   (2010-02-09 12:42) [0]

Такой вот вопрос... Есть иерархия классов A : B : C.
Я хочу из C вызвать метод foo(), реализованный в A.
Если я напишу inherited, то вызовется метод из B.
На C++ это делается просто A::foo(). А как это сделать в Delphi?
Спасибо.


 
webpauk ©   (2010-02-09 15:10) [1]

а ты не пиши inherited.
пиши A.foo()

только условие: процедура A.foo() должна быть объявлена в разделе public как class procedure.
соотв. и в классе B, и в классе С


 
Ega23 ©   (2010-02-09 15:10) [2]

A(Self).Foo


 
Ega23 ©   (2010-02-09 15:11) [3]


> только условие: процедура A.foo() должна быть объявлена
> в разделе public как class procedure.
> соотв. и в классе B, и в классе С


Эта... Иди книжки читай умные.


 
webpauk ©   (2010-02-09 15:12) [4]

TA = class
 public
   class procedure Foo(); dynamic;
 end;

 TB = class(TA)
 public
   class procedure Foo(); override;
 end;

 TC = class(TB)
 public
   class procedure Foo(); override;
 end;

class procedure TA.Show;
begin
 ShowMessage("A");
end;

class procedure TB.Show;
begin
 ShowMessage("B");
end;

class procedure TC.Show;
begin
 TA(Self).Show;
end;


 
webpauk ©   (2010-02-09 15:13) [5]


> Ega23 ©   (09.02.10 15:10) [2]
>


stack overflow


 
webpauk ©   (2010-02-09 15:13) [6]

исправление:

class procedure TC.Show;
begin
TA.Show;
end;


 
Ega23 ©   (2010-02-09 15:17) [7]


> webpauk ©   (09.02.10 15:13) [5]
> stack overflow


Немудрено. Обезьяна с гранатой - страшное дело.
Совет читать книги продолжает быть актуальным.


 
Ega23 ©   (2010-02-09 15:18) [8]

 TA = class
 protected
   procedure Foo;
 end;

 TB = class (TA)
 protected
   procedure Foo;
 end;

 TC = class (TB)
 protected
   procedure Foo;
 public
   procedure AFoo;
   procedure BFoo;
   procedure CFoo;
 end;

{ TA }

procedure TA.Foo;
begin
 ShowMessage("TA.Foo;");
end;

{ TB }

procedure TB.Foo;
begin
 ShowMessage("TB.Foo;");
end;

{ TC }

procedure TC.AFoo;
begin
 TA(Self).Foo;
end;

procedure TC.BFoo;
begin
 inherited Foo;
end;

procedure TC.CFoo;
begin
 Foo;
end;

procedure TC.Foo;
begin
 ShowMessage("TC.Foo;");
end;

procedure TForm1.Button2Click(Sender: TObject);
var
 t : TC;
begin
 t := TC.Create;
 try
   t.AFoo;
   t.BFoo;
   t.CFoo;
 finally
   t.Free;
 end;
end;



 
jack128_   (2010-02-09 18:13) [9]


> LightGreen   (09.02.10 12:42)  


для НЕвируальных методов - TA(Self).Foo();

для виртуальных/димамических так просто не получится:


type
TA = class
public
  procedure Foo(); dynamic;
end;
TAClass = class of TA;

TB = class(TA)
public
  procedure Foo(); override;
end;

TC = class(TB)
public
  procedure Foo(); override;
end;

procedure TA.Foo;
begin
ShowMessage("A");
end;

procedure TB.Foo;
begin
ShowMessage("B");
end;

procedure TC.Foo;
type
 TObjectProcedure = procedure of object;
var
 M: TMethod;
begin
 M.Code := @TA.Foo;
 M.Data := Self;
 TObjectProcedure(M)();
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
 with TC.Create do
 try
   Foo;
 finally
   Free;
 end;
end;


 
int64   (2010-02-10 16:38) [10]

LightGreen   (09.02.10 12:42)  

Много раз уже писалось, что необходимость сабжа:
1. (в большенстве случаев) связяна с кривой разработкой классов;
2. (в остальных случаях) можно обойтись без сабжа.


 
LightGreen   (2010-02-11 13:53) [11]

Спасибо. Правда метод с TObjectProcedure работает только для public методов. Уже нашёл, как сделать для других - использовать присвоение PClass(Obj) на время вызова.
Для int64 - такие ситуации не обязательно связаны с кривым дизайном. Если используется код от разных поставщиков и менять в нём ничего нельзя, а можно только наследоваться, то этот приём может понадобиться. Тем более, что в C++ это делается элементарно. И ещё - если я вообще не вызову inherited - это тоже может что-то сломать, но язык позволяет беспрепятственно.
Ещё раз спасибо всем, кто откликнулся.


 
KSergey ©   (2010-02-11 17:20) [12]

> jack128_   (09.02.10 18:13) [9]

Зачем плохому учишь? :)


 
Юрий Зотов ©   (2010-02-17 15:45) [13]

> LightGreen   (11.02.10 13:53) [11]

> использовать присвоение PClass(Obj) на время вызова.

Временная подмена ссылки на класс. Это стандарный способ вызова метода удаленного предка (да и не только предка) - но не забудьте использовать try-finally, иначе можно нахватать глюков по самое некуда.


 
icWasya ©   (2010-02-17 17:26) [14]

to LightGreen   (11.02.10 13:53) [11]
> Тем более, что в C++ это делается элементарно ?
А вот так http://rsdn.ru/forum/cpp/3705754.1.aspx


 
GrayFace ©   (2010-02-18 20:53) [15]

Тогда так:
procedure TC.Foo;
type
  TObjectProcedure = procedure of object;
var
  M: TObjectProcedure;
  class: TClass;
begin
  class:= PClass(Obj)^;
  PClass(Obj)^:= TA;
  M:= Foo;
  PClass(Obj)^:= class;
  M();  // вызов производится уже с правильной ссылкой на VMT
end;



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

Форум: "Основная";
Текущий архив: 2011.09.25;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.004 c
15-1307175573
Юрий Зотов
2011-06-04 12:19
2011.09.25
Очередной способ мошенничества?


15-1306408784
OW
2011-05-26 15:19
2011.09.25
Про ценообразование фруктов и овощей.


6-1242735446
Slavka
2009-05-19 16:17
2011.09.25
Вопрос по копированию папок с (и на) ftp целиком.


2-1307508494
mefodiy
2011-06-08 08:48
2011.09.25
Запрос с LEFT JOIN в SQL Server


2-1307469776
Nazgul1
2011-06-07 22:02
2011.09.25
Помогите сделать програму (среда Delphi)





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский