Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
7-1071524872
maxfiles
2003-12-16 00:47
2004.03.28
Можно ли создать точный таймер с интервалом в 1 мкс?


14-1077690128
Kerk
2004-02-25 09:22
2004.03.28
Злой автобус


6-1074261471
Sos
2004-01-16 16:57
2004.03.28
Помогите найти исходник проги приёма почты с 2 ящиков (pop3) и


3-1077192527
denmin
2004-02-19 15:08
2004.03.28
Помогите завязать таблицы Paradox и SQL Server 2000


1-1079008672
Nataly
2004-03-11 15:37
2004.03.28
Перевод из DOS кодировки в Windows (стандартные средства)





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский