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

Вниз

Вызов метода прапрародителя   Найти похожие ветки 

 
pvr   (2008-02-28 10:39) [0]

Как это сделать?


 
manarov   (2008-02-28 10:44) [1]

что мешает обратиться напрямую?


 
pvr   (2008-02-28 10:46) [2]

Мешает синтаксис.

Мне из метода нужно вызвать метод с тем же именем, но дедушки.


 
Сергей М. ©   (2008-02-28 10:53) [3]


> Мешает синтаксис


Эт как же он тебе мешает, позволь полюбопытствовать ?


 
Alkid ©   (2008-02-28 10:54) [4]

Метод виртуальный/динамический?
Несли нет, то так:

TMyGrandGrandParentClass(Self).MyCoolMethod();


Если метод виртуальный, то тут сложнее. Я в своё время с ассемблером извращался.


 
ЮЮ ©   (2008-02-28 10:54) [5]

Зачем же тогда наследовался от такого непутёвого сына? Надо было от дедушки и стать правильным сыном своего родителя :)


 
Palladin ©   (2008-02-28 10:55) [6]

парень видимо недоговорил, что он пытается в перекрытом методе достучаться до этого же метода но в прапраледушке... типа мы сами должны об этом догадаться...


 
pvr   (2008-02-28 10:58) [7]

Да, не договорил. Но ты догадался.


 
pvr   (2008-02-28 11:07) [8]

Палладин, ты правильно догадался. У меня есть виртуальный метод, он перекрывается в наследуемых классах. Мне нужно вызвать метод дедушки. Я это делал, но не помню, как, а нужного проекта под рукой нет. Я даже помню, что здесь был ответ на подобный вопрос, но отвечал не ты. Если помнишь - ответь и закрывай ветку.


 
Сергей М. ©   (2008-02-28 11:11) [9]


> pvr


класс "дедушки" тебе известен заранее ?


 
pvr   (2008-02-28 11:13) [10]

ЮЮ ©   (28.02.08 10:54) [5]
Зачем же тогда наследовался от такого непутёвого сына? Надо было от дедушки и стать правильным сыном своего родителя :)

У него много полезных методов, а один - не подходит.

Чувствую, народ с понятием разбрелся :( Придется заводить обычный (не виртуальный) метод в прародителе и к нему обращаться.


 
pvr   (2008-02-28 11:14) [11]

Сергей М. ©   (28.02.08 11:11) [9]
класс "дедушки" тебе известен заранее ?

Да, известен.


 
ЮЮ ©   (2008-02-28 11:29) [12]

> Придется заводить обычный (не виртуальный) метод в прародителе
> и к нему обращаться.

Почему же придется? Так наверное и надо было сделать. И вызвать его в том самом виртуальном, перекрытом наследником. Тогда и волки будут сыти и овцы целы. Наследник может изменить поведение, перекрыв виртуальный метод, но все получат доступ к полезному методу.


 
begin...end ©   (2008-02-28 11:33) [13]

var
 Obj: TSon;
begin
 Obj := TSon.Create;
 ...
 PPointer(Obj)^ := TGrandFather;
 try
   Obj.MyMethod
 finally
   PPointer(Obj)^ := TSon
 end;
 ...
end


 
Сергей М. ©   (2008-02-28 11:43) [14]

+ [13]

var
Obj: TGrandSon;
i: Integer;
Cls: TClass;
begin
Obj := TGrandSon.Create;
...

Cls := Obj.ClassType;
for i := 1 to 2 do
  Cls := Cls.ClassParent;

PPointer(Obj)^ := Cls;
try
  Obj.MyMethod
finally
  PPointer(Obj)^ := TGrandSon;
end;
...
end


 
pvr   (2008-02-28 11:47) [15]

begin...end ©   (28.02.08 11:33) [13]

Спасибо.


 
pvr   (2008-02-28 11:55) [16]

Все же в моем случае удобнее завести дополнительный статический метод :-)


 
Сергей М. ©   (2008-02-28 11:55) [17]

При чем тут синтаксис - это так и осталось тайной за семью печатями)


 
Сергей М. ©   (2008-02-28 11:57) [18]


> pvr   (28.02.08 11:55) [16]


Если внуку что-то вдруг потребовалось из-под дедушки, значит не все ладно у них в семействе)


 
pvr   (2008-02-28 12:05) [19]

Сергей М. ©   (28.02.08 11:55) [17]
При чем тут синтаксис - это так и осталось тайной за семью печатями)

В Turbo Pascal, начиная с версии 5.5 и заканчивая версией Borland Pascal 7.0 синтаксис позволял просто делать такой вызов

TGrandFather.Metod;

При этом звался статический или виртуальный метод - все равно.

А в Delphi ввели классовые методы, и указанный вызов не катит, т.к. у класса TGrandFather нет метода

class procedure TGrandFather.Metod; virtual;

Это и означает, что синтаксис не позволяет. А в семействе все в порядке :-)


 
tesseract ©   (2008-02-28 12:07) [20]


> Если внуку что-то вдруг потребовалось из-под дедушки, значит
> не все ладно у них в семействе)


Припоминаю, прошлый раз кому-то такое на собеседовании задали.


 
Alkid ©   (2008-02-28 12:12) [21]


> Сергей М. ©   (28.02.08 11:43) [14]

Поясните, плз, механизм действия данного метода? Я так понимаю, что в рантайме у объекта подменяется указатель на класс, которому тот принадлежит, что приводит к вызову метода через другую таблицу вирт. функций. Вопрос в том, насколько такой метод переносим между версиями дельфи. Если тут испольщзуются недокументированные особенности реализации объектной модели, то такой метод - это грязный хак.


 
Сергей М. ©   (2008-02-28 12:16) [22]


> в Delphi ввели классовые методы, и указанный вызов не катит


Да ты что ?!

Вот чудеса-то !)

А у меня почему-то в Д7 "катит":

TForm.InheritsFrom(TObject);


На этой строчке компилятор не посылает меня лесом, значит с синтаксисом усе в порядке. А что при этом происходит в ран-тайм - это неважно, бо к синтаксису это не имеет ни малейшего отношения.

Синтаксис имеет отношение к дизайн-тайм, а не к ран-тайм)


> в семействе все в порядке


Все же позволю себе усомниться)


 
Сергей М. ©   (2008-02-28 12:17) [23]


> Alkid ©   (28.02.08 12:12) [21]


А это и есть грязный хак)
Как и собственно постановка задачи.
Потому и [18])


 
Ega23 ©   (2008-02-28 12:19) [24]


> Alkid ©   (28.02.08 10:54) [4]
> Если метод виртуальный, то тут сложнее. Я в своё время с
> ассемблером извращался.


TGUIModalView, у меня все ходы записаны..  :)


 
Alkid ©   (2008-02-28 12:19) [25]


> А это и есть грязный хак)
> Как и собственно постановка задачи.
> Потому и [18])

Ну вообще постановка задачи тут не фонтан, при хорошем проектировании таких ситуаций возникать не должно. В любом случае, лучше вынести нужный функционал в невиртуальную функцию, чем применять такие финты ушами.


 
pvr   (2008-02-28 12:20) [26]

Сергей М. ©   (28.02.08 12:16) [22]
TForm.InheritsFrom(TObject);

Это классовый метод. А у меня не классовый.


 
pvr   (2008-02-28 12:22) [27]

Alkid ©   (28.02.08 12:19) [25]
Ну вообще постановка задачи тут не фонтан, при хорошем проектировании таких ситуаций возникать не должно. В любом случае, лучше вынести нужный функционал в невиртуальную функцию, чем применять такие финты ушами.

Согласен.


 
Сергей М. ©   (2008-02-28 12:24) [28]


> указанный вызов не катит


Зато замечательно катит приведение типа объекта к требуемому классу.
Но в случае виртуального метода он, разумеется, неприменим.


 
Alkid ©   (2008-02-28 12:29) [29]


> TGUIModalView, у меня все ходы записаны..  :)

Ага. Кстати, поступил я тогда по-свински. Надо было рефакторить :)


 
pvr   (2008-02-28 12:29) [30]

Сергей М. ©   (28.02.08 12:24) [28]
Но в случае виртуального метода он, разумеется, неприменим.

Конечно, неприменим, Отсюда и вопрос.

Насчет "хорошего проектирования". Еще раз повторю, в Turbo Pascal вызов TGrandFather.Metod; работал как надо. И это считалось нормальным проектированием. Но в Delphi этой возможностью пожертвовали ради классовых методов, и проектирование стало плохим :-)


 
Сергей М. ©   (2008-02-28 12:34) [31]


> в Turbo Pascal вызов TGrandFather.Metod; работал как надо


Но это же и в TP не есть твой случай !

Ты-то ведешь речь о методе объекта, при этом резонный вопрос возникает - метод Method какого конкретно объекта класса TGrandFather ты вызываешь строчкой "TGrandFather.Metod" ?


 
pvr   (2008-02-28 12:38) [32]

Сергей М. ©   (28.02.08 12:34) [31]
Ты-то ведешь речь о методе объекта, при этом резонный вопрос возникает - метод Method какого конкретно объекта класса TGrandFather ты вызываешь строчкой "TGrandFather.Metod" ?

Там не было классовых методов вообще. Оператор TGrandFather.Metod вызывал метод экземпляра указанного типа (классов тоже не было, были объекты), при этом метод мог быть как статическим, так и виртуальным.


 
Amoeba ©   (2008-02-28 12:46) [33]


> Но в Delphi этой возможностью пожертвовали ради классовых
> методов, и проектирование стало плохим :-)
>

LOL!


 
pvr   (2008-02-28 12:47) [34]

Сергей М. ©   (28.02.08 12:34) [31]

Понял твое недопонимание.

procedure TInherited.Method;
begin
 TGrandFather.Method;
 ...
end;

Экземпляр типа TInherited из своего метода вызывает метод дедушки. При этом используется контекст экземпляра.


 
Сергей М. ©   (2008-02-28 12:48) [35]


> проектирование стало плохим


"Вы не любите кошек ? Да вы просто не умеете их готовить !" (c)


 
Сергей М. ©   (2008-02-28 12:50) [36]


> pvr   (28.02.08 12:47) [34]


А какое, спрашивается, право внук имеет вмешиваться в дела дедушки ?)


 
Сергей М. ©   (2008-02-28 12:53) [37]

А если уж, по-твоему, и имеет, то в Делфи все это решаемо и без грязного хака.
Просто следует грамотно приспособить для этой цели механизм вызова одноименного метода прямого предка - inherited.


 
pvr   (2008-02-28 12:53) [38]

Может, кто-нибудь продолжит растолковывать тебе принципы ООП, а я уже устал. Прости.


 
Сергей М. ©   (2008-02-28 12:55) [39]


> кто-нибудь продолжит растолковывать тебе принципы ООП


Сгораю от нетерпения.


 
Palladin ©   (2008-02-28 13:25) [40]


> pvr   (28.02.08 12:53) [38]

возникшая необходимость обращения к методу, дедушки, но не разрешенная по спроектированной диаграмме класов - назвается ошибкой проектирования, кою необходимо исправить пока не поздно.


 
pvr   (2008-02-28 13:40) [41]

В чем ошибка проектирования?

procedure TGrand.BaseInitData;
begin
 ...
end;

procedure TGrand.InitData; // virtual;
begin
 BaseInitData;
 ...
end;

procedure TFather.InitData; // override;
begin
 inherited;
 ...
end;

procedure TMyClass.InitData; // override;
begin
 BaseInitData;
 ...
end;


 
pvr   (2008-02-28 13:43) [42]

Неправильно понял слова "не разрешенная по спроектированной диаграмме классов". Согласен.


 
Сергей М. ©   (2008-02-28 13:49) [43]


> procedure TMyClass.InitData; // override;
> begin
>  BaseInitData;
>  ...
> end;
>


Ну и где здесь попытка вызова виртуального метода деда ?


 
pvr   (2008-02-28 13:50) [44]

Здесь нет.


 
Сергей М. ©   (2008-02-28 13:54) [45]

так покажи, где она у тебя есть .. пусть и с "ошибкой синтаксиса" ..


 
pvr   (2008-02-28 14:00) [46]

Удалено модератором


 
Сергей М. ©   (2008-02-28 14:10) [47]


> pvr   (28.02.08 14:00) [46]


Вот я и хочу понять, чем оправдана попытка такого рода "вмешательства".
А из приведенного тобой кода совершенно неясно, где в теле TMyClass.InitData происходит попытка вызова какого-либо вирт.метода класса TGrand


 
pvr   (2008-02-28 14:11) [48]

Удалено модератором


 
Сергей М. ©   (2008-02-28 14:12) [49]

Удалено модератором


 
DiamondShark ©   (2008-02-28 14:12) [50]

Удалено модератором
Примечание: внимательно изучаем п. 11


 
pvr   (2008-02-28 14:15) [51]

Удалено модератором


 
Сергей М. ©   (2008-02-28 14:18) [52]

Удалено модератором



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

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

Наверх




Память: 0.59 MB
Время: 0.032 c
15-1203053813
Tornado
2008-02-15 08:36
2008.03.30
Как подключить к инету два компа?


15-1203214944
Tirael
2008-02-17 05:22
2008.03.30
вирус чтоли...


11-1169376813
progbeg
2007-01-21 13:53
2008.03.30
Проблема с KOLOpenDirDialog


2-1204396606
максим
2008-03-01 21:36
2008.03.30
memo с канвой


2-1204467333
Kiril
2008-03-02 17:15
2008.03.30
Как в SpinEdit вводить десятичные числа?