Форум: "Основная";
Текущий архив: 2004.03.28;
Скачать: [xml.tar.bz2];
ВнизКак определять абстрактные методы? Найти похожие ветки
← →
BPK (2004-03-09 14:24) [0]Существует класс:
TMyAbstract=class
protected
FList:TList;
function GetItem(Num:integer):TCustomRecord;
procedure SetItem(Num:integer; OfmRec:TCustomRecord);
function GetItemsCount:integer;
public
function AddItem(OfmRec:TCustomRecord):integer;
procedure DeleteItem(Num:integer);
property Items[Num:integer]:TCustomRecord read GetItem write SetItem; default;
property ItemsCount:integer read GetItemsCount;
procedure Clear;
procedure CopyFrom(SL:TMyAbstract);
end;
Теперь представьте, что из него нужно сделать абстрактный класс, т.е. методы GetItem, SetItem, AddItem, DeleteItem, Clear, CopyFrom,
а также свойство Items
должны стать абстрактными.
С методом Clear никаких проблем нет, а вот с остальными - загвоздка.
Проблема заключается в том, что тип, замещённый мною для наглядности словом "TCustomRecord" будет определён только в классах-потомках. Известно только то, что это во всех случаях будет структура (record).
Вторая проблема в том, что для методов-функций нужно указать тип возвращаемого результата, а он опять-таки не определён.
Третья проблема: в свойстве Items тоже применяется тот же самый тип (т.е. как указать, что Items, GetItem и SetItem имеют один и тот же общий тип данных, но пока он неизвестен?)
И ещё: существует ли такое понятие, как абстрактное свойство? Если да, то как его объявлять?
← →
Тимохов © (2004-03-09 14:27) [1]вместо TCustomRecord используйте:
либо все-таки класс, либо просто pointer и в потомках переопределяйте методы с явным приведением типа.
← →
YuRock © (2004-03-09 14:30) [2]Для методов директивы "virtual; abstract" должны помочь
> абстрактное свойство
Встречал только разве-что если оно определено через read/write абстрактные методы.
← →
BPK (2004-03-09 14:32) [3]>Для методов директивы "virtual; abstract" должны помочь
Да я не об этом. Я спрашиваю: значит ли это, что вместо неизвестного типа данных в абстрактных методах можно подставлять совершенно любой тип из числа определённых на текущий момент?
← →
Тимохов © (2004-03-09 14:34) [4]
> BPK (09.03.04 14:32) [3]
Говорю же - пользуйтесь pointer и приводите тип к какому захотите в потомках.
Явно, то о чем вы справшиваете, в дельфи нет.
← →
BPK (2004-03-09 14:34) [5]>Встречал только разве-что если оно определено через
>read/write абстрактные методы
А как указывать неизвестный тип свойства?
← →
Тимохов © (2004-03-09 14:35) [6]никак
← →
BPK (2004-03-09 14:36) [7]>никак
т.е. даже не через pointer, а вообще ничего не писать?
← →
BPK (2004-03-09 14:39) [8]Если вообще ничего не писать, то ругается.
← →
YuRock © (2004-03-09 14:39) [9]> А как указывать неизвестный тип свойства?
Пусть есть переменная varObj: TObject
Попробовать узнать ее настоящий тип можно, например, такими путями:
1. if varObj.ClassName = "T_Неизвестный_тип" then ...;
2. if varObj.ClassType = T_Неизвестный_тип then ...;
...
← →
Тимохов © (2004-03-09 14:39) [10]
> т.е. даже не через pointer, а вообще ничего не писать?
не понял фразу.
← →
YuRock © (2004-03-09 14:41) [11]> вместо неизвестного типа данных в абстрактных методах можно подставлять совершенно любой тип из числа определённых на текущий момент?
Если это объект - конечно надо TObject "подставлять"
← →
BPK (2004-03-09 14:41) [12]>> т.е. даже не через pointer, а вообще ничего не писать?
>не понял фразу.
Т.е.
property Items[Num:integer] read GetItem write SetItem; default;
← →
BPK (2004-03-09 14:42) [13]>Если это объект - конечно надо TObject "подставлять"
А если record?
← →
Тимохов © (2004-03-09 14:44) [14]
> BPK (09.03.04 14:42) [13]
Ну вы и упертый :))))0
Если record, то кроме как через pointer хорошо не сделаете.
← →
YuRock © (2004-03-09 14:44) [15]> BPK (09.03.04 14:41) [12]
Пусть GetItem будет возвращать TObject, а у SetItem будет параметр Value: TObject
← →
YuRock © (2004-03-09 14:45) [16]Извините, я слово record только щас заметил
← →
YuRock © (2004-03-09 14:47) [17]А в чем с record проблема? Определить тип, конечно, неудастся (это вообще нонсенс - тип структуры :)), только размер разве-что...
← →
BPK (2004-03-09 14:49) [18]Спасибо. Всё уразумел. Буду писать pointer. Вообще, как я понял, там всё равно какой тип указывать, лишь бы этот тип был определён.
Всё равно определение метода поменяется.
Просто меня немного смутили объявления в модуле Classes такого рода:
function Read(var Buffer; Count: Longint): Longint; virtual; abstract;
function Write(const Buffer; Count: Longint): Longint; virtual; abstract;
Заметьте: здесь тип параметра Buffer не указан.
>Ну вы и упертый
Нет, я не упёртый. Это был диалог с YuRock.
← →
Тимохов © (2004-03-09 14:52) [19]
> BPK (09.03.04 14:49) [18]
Тип buffer не указан, т.к. это по сути тот же pointer, только описанный неявно (синтаксис немного другой), а так, тот же pointer.
← →
BPK (2004-03-09 18:58) [20]А вот Вам и ошибочка: не получается.
TAbstractItem=pointer;
TItemsList=class
private
...
function GetItem(Num:integer):TAbstractItem; virtual; abstract;
...
public
...
end;
TOfmList=class(TItemsList)
private
...
function GetItem(Num:integer):TOfmRecord; override;
...
public
...
end;
Пишет:
Declaration of "GetItem" differs from previous declaration.
А у меня нет возможности чётко указать тип данных, возвращаемых функцией абстрактного класса.
← →
Тимохов © (2004-03-09 19:00) [21]А на фига вам virtual?
Что вы собираетесь добиться через такую конструкцию?
Мне сложно представить :)))))
← →
Тимохов © (2004-03-09 19:03) [22]Имхо вы рановато взялись за абстракцию.
Все-таки немного знаний ооп в дельфи не хватает.
Вы вообще чего хотите добится?
← →
icWasya © (2004-03-09 19:13) [23]человек хочет сделать Сишный vector<TAbstractItem>
надо объяснить, чтобы и не пытался
← →
Тимохов © (2004-03-09 19:16) [24]
> надо объяснить, чтобы и не пытался
потом рождаются легенды, что дельфи плохой язык :(((((
← →
YuRock © (2004-03-09 19:23) [25]> icWasya © (09.03.04 19:13) [23]
> человек хочет сделать Сишный vector<TAbstractItem>
Что он хотел сделать? Что это за "function GetItem(Num:integer):TOfmRecord; override;"????
Что override? То, что в базовом классе privat? Что, Си позволяет перекрывать privat?
← →
YuRock © (2004-03-09 19:26) [26]Вообще мне нравится! Делать абстрактные методы недоступными для наследников! А виртуальные - с разными типами параметров - тоже хороший стиль... Как себя комписятор поведет? Тяжело сказать...
← →
Матлабист (2004-03-09 19:32) [27]Посмотри, как сделаны коллекции в Classes... Они не подойдут?
← →
Defunct © (2004-03-09 19:40) [28]> Что override? То, что в базовом классе privat? Что, Си позволяет перекрывать privat?
Какая разница что перекрывать? Private секция определяет только область видимости функции. Вообще совет избавиться от Record, работать только с классами.TMyAbstratctClass = Class(_)
Private
FItems : Array of TMyAvstractClass;
Function GetItem(Num:Integer):TMyAbstractItem;virtual;abstract;
Public
Property Items[Num:Integer]:TMyAbstractClass Read GetItem;
End;
TMyObj1 = Class(TMyAbstratctClass)
Private
Function GetItem(Num:Integer):TMyAbstractItem;override;
End;
Function TMyObj1.GetItem;
Begin
If Num<Length(FItems) Then Result := FItems[Num];
End;
Хотя такую функцию можно определить и не астрактно в базовом классе.
← →
YuRock © (2004-03-09 19:52) [29]> Defunct © (09.03.04 19:40) [28]
> Какая разница что перекрывать? Private секция определяет только область видимости функции.
И все-же я не понимаю, как можно перекрыть метод, которого нет... может, объясните?
← →
vuk © (2004-03-09 20:02) [30]to YuRock:
>как можно перекрыть метод, которого нет... может, объясните?
А кто сказал, что его нет?
← →
Тимохов © (2004-03-09 20:05) [31]Реально не могу прочухать, что хочет сделать автор :))))))
← →
Гаврила (2004-03-09 20:09) [32]Не определяйте абстракнтые методы через Pointer - дурной стиль, запутаетесь потом.
Более-менее жесткая типизация для того и сделана, чтобы избежать лишних ошибок.
Лучше заменить TCustomRecord на абстрактный класс.
Тем более что поля класса реально все равно хранятся как record.
А первого предка всех TCustom{Record}Class определите в этом же модуле
такое мое глубочайшее ИМХО
← →
Anatoly Podgoretsky © (2004-03-09 20:09) [33]YuRock © (09.03.04 19:52) [29]
Не волнуйся это астракция, метода нет, но перекрыть пожалуйста, компилятор предупрежден об этом волшебным словом abstract
← →
Serginio666 (2004-03-09 20:11) [34]http://www.rsdn.ru/article/Delphi/delphiabs.xml
← →
Тимохов © (2004-03-09 20:11) [35]
> Гаврила (09.03.04 20:09) [32]
Про классы автору уже советовали.
Вроде как ему нужно именно рекордами.
> Тем более что поля класса реально все равно хранятся как
> record.
Не совсем - в классе выравнивание нельзя отключить, а record - можно (packed). В случае критического отношения к занимаемой памяти может быть важно. Не зная задачи автора сложно понять важно ли ему оптимизация по занимаемой памяти или нет.
← →
Гаврила (2004-03-09 20:15) [36]>>в классе выравнивание нельзя отключить
Можно
TMyClass = packed class(TObject)
← →
YuRock © (2004-03-09 20:16) [37]> vuk © (09.03.04 20:02) [30]
Нет - в смысле в области видимости. При попытке написать override еще компилятор должен ошибку выдать (не считая тех редки случаев, когда базовый класс и наследник описаны в одном модуле).
А если попытаться изменить типы параметров и/или их количество - то уже ничего не поможет...
← →
YuRock © (2004-03-09 20:25) [38]> Anatoly Podgoretsky © (09.03.04 20:09) [33]
Ну? Я что, против? Я не пойму, как можно перекрыть абстрактный (а значит - виртуальный) метод, которого нет в базовом классе? (нет в области видимости)
← →
Тимохов © (2004-03-09 20:28) [39]
> Гаврила (09.03.04 20:15) [36]
Согласен полностью.
Но все равно на 4 байта больше (первые 4 байте ссылка на класс).
Мало ли, может автору нужно 5 млн объектов (а это все-таки лишних 20 мег:)))))
← →
vuk © (2004-03-09 20:30) [40]Если говорить об виртуальных методах, то абстрактный метод - это виртуальный метод, не имеющий реализации. То есть имеется определение заголовка метода и место этого метода в VMT. То есть говорить о том, что метода нет малость не совсем верно.
to YuRock:
>Нет - в смысле в области видимости.
Вы же так и написали - не считая тех редки случаев, когда базовый класс и наследник описаны в одном модуле. То есть в некоторых случаях все-таки есть.
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2004.03.28;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.031 c