Форум: "Основная";
Текущий архив: 2004.03.28;
Скачать: [xml.tar.bz2];
ВнизО наследовании классов Найти похожие ветки
← →
Ш-К (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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.033 c