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

Вниз

О наследовании классов   Найти похожие ветки 

 
Ш-К   (2004-03-09 14:07) [0]

Когда при наследовании меняются типы полей.

Пример такой:

 TMyCustomList = class
   Item: TMyCustomItem;
   procedure Run;
 end;

 TMyList = class(TMyCustomList)
   Item: TMyItem(class(TMyCustomItem));
 end;

procedure TMyCustomList.Run;
begin
 Item.initialize;
end;

Соответственно, когда я вызываю TMyList.Run, вызывается метод предка, в котором Item типа TMyCustomItem, а не TMyItem.

Можно в TMyList переописать метод Run:

procedure TMyList.Run;
begin
 Item.initialize;
end;

Как видно, statement-ы метода идентичны. А если будет идентичность других методов(как у меня) и не в одном потомке(как у меня)?

Как мне перепроектировать предка изначально, чтобы не разрабатывать потомков в Copy/Paste?


 
Плохиш   (2004-03-09 14:12) [1]

Для начала не мешало бы основы ООП подучить


 
Тимохов ©   (2004-03-09 14:13) [2]

Сделайте initialize virtual.
Или я что-то в вопросе не понял?


 
Ш-К   (2004-03-09 14:18) [3]

Тимохов ©   (09.03.04 14:13) [2]
Делал. Этот метод будет у экземпляров разных классов.

Item: TMyItem;
и
Item: TMyCustomItem;


 
Тимохов ©   (2004-03-09 14:22) [4]

Сделайте так.

TMyCustomList = class
  fItem: TMyCustomItem;
  function Item: TMyCustomItem;
  procedure Run;
end;

TMyList = class(TMyCustomList)
  function Item: TMyItem;
end;

function TMyCustomList.Item: TMyCustomItem;
begin
  result := fItem;
end;

function TMyList.Item: TMyItem;
begin
  result := TMyItem(inherited Item);
end;

Initialize описан в TMyCustomItem.
Его вызов fItem.Initialize


 
Ш-К   (2004-03-09 14:31) [5]

Если каждое поле в потомке так оформлять, и для каждого потомка, то не вищу преймуществ перед Copy/Paste.


 
Тимохов ©   (2004-03-09 14:34) [6]

читайте 1.
имхо автор 1 верно фишку просек.


 
Ш-К   (2004-03-09 14:37) [7]

А чем я сейчас занимаюсь, как не изучением ООП?
И что у меня не могут возникать вопросы?


 
Тимохов ©   (2004-03-09 14:38) [8]


> Ш-К   (09.03.04 14:37) [7]

Не обижайтесь.
В 4 я привел стандартный метод для решения вопросов, аналогичным вашим.
Если не нравится делайте копи\паст. Дело ваше.


 
Тимохов ©   (2004-03-09 14:42) [9]


> Ш-К   (09.03.04 14:37) [7]

да!
к 4 добавте 2, если initialize может переопределяться в потомках TMyCustomItem.


 
Ш-К   (2004-03-09 14:53) [10]

Тимохов ©   (09.03.04 14:22) [4]

> Сделайте так.
>
> TMyCustomList = class
>   fItem: TMyCustomItem;
>   function Item: TMyCustomItem;
>   procedure Run;
> end;

Если я вызову метод Run из TMyList, он будет вызван из предка, где fItem: TMyCustomItem; И доступа к Item как к TMyItem я всеравно не получу.
ИМХО?


 
Тимохов ©   (2004-03-09 14:59) [11]

Если вы вызовете Run у TMyList, то реально будет вызван

procedure TMyCustomList.Run;
begin
fItem.initialize;
end;

т.к. fItem: TMyCustomItem и Initialize virtual, то будет вызыван Initialize у TMyItem.


 
Ш-К   (2004-03-09 16:05) [12]

Вот готовый код:

 TCustItem = class(TObject)
   Field: string;
   procedure initialize; virtual;
 end;

 TMyItem = class(TCustItem)
   procedure initialize; virtual;
 end;

 TCustList = class(TObject)
   fitem: TCustItem;
 public
   constructor Create;
   destructor Destroy;
   function Item: TCustItem;
   procedure Run;
 end;

 TMyList = class(TCustList)
   fitem: TMyItem;
 public
   function Item: TMyItem;
   constructor Create;
 end;

.....

procedure TCustItem.initialize;
begin
 Field := "TCustItem";
end;

procedure TMyItem.initialize;
begin
 Field := "TMyItem";
end;

constructor TCustList.Create;
begin
 fItem := TCustItem.Create;
end;

destructor TCustList.Destroy;
begin
 fItem.Free;
end;

function TCustList.Item: TCustItem;
begin
 result := fItem;
end;

procedure TCustList.Run;
begin
 fItem.initialize;
end;

constructor TMyList.Create;
begin
 inherited Create;
 fItem.Free;
 fItem := TMyItem.Create;
end;

function TMyList.Item: TMyItem;
begin
 result := TMyItem(inherited Item);
end;

И теперь при вызове:

procedure TForm1.Button1Click(Sender: TObject);
var
 My: TMyList;
begin
 My := TMyList.Create;
 My.Run;
 My.Free;
end;

В методе Run вызывается Initialize от TCustItem.

Что не так?


 
Тимохов ©   (2004-03-09 16:14) [13]


>  TMyItem = class(TCustItem)
>    procedure initialize; virtual;
>  end;
>


надо оverride.

Включите в опциях проекта warnings, и соответственно читайте их - в данном случае дельфи вам давала warning.


 
Тимохов ©   (2004-03-09 16:20) [14]

Подумайте об использовании конструкции TCustItemClass = class of TCustItem - так будет красивей и правильней, чем в конструкторе потомков удалять fItem, созданный в предке.


 
Ш-К   (2004-03-09 16:24) [15]


> надо оverride.

Ничего не изменилось. Метод предка.


 
Тимохов ©   (2004-03-09 16:29) [16]

а на фига вам fitem у TMyList.
уберите на фиг. Все будет ок.
Про 13 не забывайте.


 
Ш-К   (2004-03-09 16:37) [17]

Непонятно как, но работает. Спасибо.


 
Тимохов ©   (2004-03-09 16:39) [18]


> Ш-К   (09.03.04 16:37) [17]

почему не понятно.
у вас теперь есть исходник для изучения.
изучайте.
тут все логично.
учтите 14 - также полезно



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

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

Наверх




Память: 0.51 MB
Время: 0.043 c
7-1073513396
Кен
2004-01-08 01:09
2004.03.28
Где находится Журнал ? Как его получить и как с ним работать ?


1-1078866459
tytus
2004-03-10 00:07
2004.03.28
Как сохранять объект в TreeView?


3-1077794897
mOOx_
2004-02-26 14:28
2004.03.28
который из IB не имеет зарезервироанного...


14-1078368601
Kyrt
2004-03-04 05:50
2004.03.28
e-mail


1-1079027626
DDA
2004-03-11 20:53
2004.03.28
Зарегистрирована горячая клавиша или нет