Вызов методов потомка?

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Вызов методов потомка?

Сообщение dionic » 27.05.2010 13:46:01

Народ всем привет!
Подскажите кто знает...
Каким образом, если вообще возможно, можно вызвать метод потомка, у объекта класса родителя, если у родителя этот метод вообще не объявлен?

Ну ,например, есть классы TMyClass0, а TMyClass1 - потомок. Создали объект obj1 класса TMyClass1, у него есть новый метод не объявленный в TMyClass0, допустим function show.
Затем переменной obj0 класса TMyClass0 присвоили объект obj1. Как вызвать show?
dionic
новенький
 
Сообщения: 90
Зарегистрирован: 17.06.2009 21:00:08

Re: Вызов методов потомка?

Сообщение Light13 » 27.05.2010 13:49:16

возможно так
Код: Выделить всё
  TMyClass1(obj0).show;
Аватара пользователя
Light13
постоялец
 
Сообщения: 127
Зарегистрирован: 17.07.2009 07:50:10
Откуда: Челябинск

Re: Вызов методов потомка?

Сообщение tria » 27.05.2010 13:55:07

Если все твой код - применяй в родителе описание этого метода как abstract
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Re: Вызов методов потомка?

Сообщение dionic » 27.05.2010 13:59:30

tria писал(а):Если все твой код - применяй в родителе описание этого метода как abstract


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

Интересно можно ли определить какого реально класса объект и в соответствии с этим вызвать метод этого класса?
dionic
новенький
 
Сообщения: 90
Зарегистрирован: 17.06.2009 21:00:08

Re: Вызов методов потомка?

Сообщение VirtUX » 27.05.2010 14:01:14

хм... может имелось ввиду это:
Код: Выделить всё
type
mc1 = class
  private
    procedure MChild;
  end;

  mc2 = class(mc1)
  public
    procedure show;
  end;

var
  o: mc1;

procedure mc2.show;
begin
  ShowMessage('yes');
end;

procedure mc1.MChild;
var
  mc: mc2;
begin
  mc := mc2.Create;
  mc.show;
  FreeAndNil(mc);
end;   

begin
  o.MChild;
end; 
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Вызов методов потомка?

Сообщение dionic » 27.05.2010 14:19:31

Не совсем , вроде бы...
Я наверное не особо понятно объясняю.

Допустим имеем класс-родитель, и не хотим менять его или добавлять новые методы к нему - Tparent. И имеем классы потомки этого класса. Допустим TChild, в которых прописаны новые методы. Затем в каком-то обработчике мы пишем создание объекта класса TChild

Функция CreateClass вызывает create указанного класса

Код: Выделить всё
type
Tparent = class
private
   procedure MChild;
end;

TChild = class
public
   function show;
end;

// где-то в обработчике ...
var lobj : Tparent;
begin

lobj:= CreateClass('имя класса потомка');

// вот потом необходимо вызвать метод show потомка который получился...


end;

dionic
новенький
 
Сообщения: 90
Зарегистрирован: 17.06.2009 21:00:08

Re: Вызов методов потомка?

Сообщение VirtUX » 27.05.2010 14:22:09

dionic писал(а):Интересно можно ли определить какого реально класса объект

Код: Выделить всё
MyObject.ClassType


Добавлено спустя 4 минуты 25 секунд:
Код: Выделить всё
var lobj: TParent; //по сути некоторый адрес
begin
lobj:= TChild.Create; //Выделили память для объекта с его методами
end;

далее где-то в обработчике:

TChild(lobj).show; //Вызываем дочерний метод (распределенный в памяти)
lobj.ParentMethod; //Вызываем собственные методы


Добавлено спустя 8 минут 26 секунд:
Только я не уверен, что не останется мусора в ОЗУ после FreeAndNil(lobj); Наверно лучше делать так:
Код: Выделить всё
TChild(lobj).free;
lobj := nil;
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Вызов методов потомка?

Сообщение dionic » 27.05.2010 14:40:01

VirtUX писал(а):Добавлено спустя 4 минуты 25 секунд:
Код: Выделить всё
var lobj: TParent; //по сути некоторый адрес
begin
lobj:= TChild.Create; //Выделили память для объекта с его методами
end;

далее где-то в обработчике:

TChild(lobj).show; //Вызываем дочерний метод (распределенный в памяти)
lobj.ParentMetoth; //Вызываем собственные методы


Ну вы всё правильно пишете но только для частного случая, у меня просто функция CreateClass вызывает конструкторы классов потомков TParent и возвращает эти объекты. Т.е. lobj:= TChild.Create; - это частный случай, CreateClass('имя класса') - общий, я туда передаю название класса потомка Tparent.
И поэтому потом я не знаю как вызвать метод потомка, т.к. у меня lobj класса TParent. Хотя когда идет отладка он TChild.
Но написать TChild(lobj).show я не могу , т.к какой конкретно класс сейчас я не знаю...
Можно конечно проверять ClassType и в соответствии с этим вызывать методы дочерних классов таким образом...
dionic
новенький
 
Сообщения: 90
Зарегистрирован: 17.06.2009 21:00:08

Re: Вызов методов потомка?

Сообщение VirtUX » 27.05.2010 14:42:56

dionic писал(а):Можно конечно проверять ClassType и в соответствии с этим вызывать методы дочерних классов таким образом...

В принципе я так у себя и делаю. Подругому пока даже и не задумывался :)
Единственный минус в таком подходе - ограниченность классов. Но если пустить полностью все на самотек - это уже будет прототип Ии ;) Ведь методы дочерних тоже могут быть непредсказуемые...
Последний раз редактировалось VirtUX 27.05.2010 14:46:25, всего редактировалось 1 раз.
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Вызов методов потомка?

Сообщение dionic » 27.05.2010 14:46:14

Ладно спасибо за ответы =)
dionic
новенький
 
Сообщения: 90
Зарегистрирован: 17.06.2009 21:00:08

Re: Вызов методов потомка?

Сообщение Odyssey » 27.05.2010 15:30:51

Вместо проверки ClassType можно пользоваться операторами is и as.
Безопасный способ (если lobj не является TChild, ничего не произойдёт):
Код: Выделить всё
if lobj is TChild then
  TChild(lobj).show

Опасный способ (если lobj не является TChild, будет Exception):
Код: Выделить всё
(lobj as TChild).show

Во втором случае, если будет Exception, то он будет более понятный чем при просто TChild(lobj).show.
Odyssey
энтузиаст
 
Сообщения: 580
Зарегистрирован: 29.11.2007 17:32:24

Re: Вызов методов потомка?

Сообщение VirtUX » 27.05.2010 18:12:51

Odyssey писал(а):Вместо проверки ClassType можно пользоваться операторами is и as.

В любом случае - это не решает проблему.
Мне тут пришла мысль в голову, а если так:
Код: Выделить всё
type
TObjProcedure = procedure of object;
{Родитель}
TAnyParent = class
  property ChildMethod: TObjProcedure;
  procedure {или function} CreateClass(Sender: TObject);
end;
{Дочерний}
TChild = class(TAnyParent)
  procedure AnyChildMethod;
  constructor Create;
end;

{Переменные}
var
  PrObj = TAnyParent;

implementation

{Некоторая процедура}
procedure AnyProc;
begin
  if PrObj.ChildMethod <> nil then PrObj.ChildMethod; //Вызов дочернего метода
end;

constructor TChild.Create;
begin
  inherited Create;
  ChildMethod := @AnyChildMethod; //Это же можно делать и по любому событию в дочернем классе - не только при создании.
end;

end.

Смысл в: определении процедурной переменной в родителе, для помещения туда (в некоторый момент времени) дочернего метода перед вызовом его из родителя.
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Вызов методов потомка?

Сообщение Mr.Smart » 27.05.2010 19:44:50

VirtUX
Зачем городить такой огород?
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: Вызов методов потомка?

Сообщение VirtUX » 27.05.2010 19:52:43

Mr.Smart писал(а):Зачем городить такой огород?

А как проще?
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Вызов методов потомка?

Сообщение Mr.Smart » 27.05.2010 19:59:00

Самый простой и правильный способ будет создание в родители данного только пустого, а в наследниках перекрывать его.
Если уж это никак не подходит, то делать как написал Odyssey
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

След.

Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 49

Рейтинг@Mail.ru