Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Компоненты Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.05.2011, 08:54   #1
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию разные классы, одна процедура

у меня есть несколько разных классов но в каждом из них есть одинаковая процедура.
я создаю несколько экзепляров этих классов и запихиваю их в array of TObject
чтобы потом в цикле вызвать процедуру в каждом экземпляре:

for...
(Items[i] as TMyClass).Go;

где TMyClass - пустой класс, в котором описана одинаковая процедура,
содержащаяся во всех остальных классах.
объявления процедур везде совпадают.

компилятор, разумеется, считает себя умнее меня,
но я то знаю что в Items[i] есть процедура Go.
и вообще хотелось бы Items[i].Go; но это не позволяет скомпилить компилятор.
(Items[i] as TMyClass).Go компилится, но при выполнении выдает ошибку
(точно не помню, что-то про несовпадение классов)
делфи конечно прав, классы не совпадают,
но я все-таки настаиваю что процедура Go есть и ее надо запустить.

что можно сделать?
xrob вне форума Ответить с цитированием
Старый 16.05.2011, 09:19   #2
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию

м...
нашел способ.
описал одинаковую процедуру в классе,
от которого потом унаследовал все остальные классы.
так работает...
но есть еще какие-нибудь варианты?
что если я не хочу наследовать новые классы?
xrob вне форума Ответить с цитированием
Старый 16.05.2011, 09:20   #3
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

может вам использовать наследование?
сделать абстрактный класс родитель(в нем абстрактная процедура ваша), а остальные ваши классы наследовать от него, и реализовать эту самую процедуру.
потом вам просто будет нужен массив этого самого абстрактного класса.
Цитата:
но есть еще какие-нибудь варианты?
ну разве что интерфейсы, но мне в Делфи они не нравятся.
да и по мне это самое то для применения наследования.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 16.05.2011, 09:32   #4
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию

хорошо, тогда еще вопрос.
что такое абстрактный класс?
это чисто разговорное определение,
или абстрактный класс чем-то отличается от обычного?

вот я создал

TBase = class
procedure Test1; virtual;
end;

а потом

TNew = class(TBase)
n:integer;
s:string;
procedure Test1; override;
end;

а что вы там про интерфейсы говорили?
что это такое? т.е. я примерно представляю что это
(набор функций и процедур характерных для объекта, так?)
каким образом здесь это использовать?
xrob вне форума Ответить с цитированием
Старый 16.05.2011, 09:45   #5
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,527
По умолчанию

Цитата:
что такое абстрактный класс?
это чисто разговорное определение,
или абстрактный класс чем-то отличается от обычного?
Абстрактный класс класс в котором определены абстрактные методы
абстрактный метод метод имеющий определение но не имеющим реализации в данном классе.(Его реализация будет выполнена в классах наследниках).

Код:
TBase = class
procedure Test1; virtual; abstract;
end;
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 16.05.2011, 09:55   #6
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

вообще в Делфи нет понятия абстрактного класса(это с шарпа привычка), но я имел в виду именно ваш класс TBase

немного стыдно признаться, но с интерфейсами в Делфи я не работал, поэтому код привести не могу.
по сути сведется к тому что вы объявите интерфейс, и уже в ваших классах будете его реализовывать.(добавляя интерфейс в список наследников)
и потом приводя к типу интерфейса просто исполнять то что вам надо.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 17.05.2011, 16:25   #7
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию

возникла проблема.
в экземплярах унаследованных от моего "абстрактного" класса есть поле Area:TRect;
в абстрактном классе я его тоже объявил.
есть array of TBase, в котором лежат объекты разных классов, унаследованных от TBase.
проблема в том что не могу достучаться до поля Area =(
Items[i].area.right;
т.е. достучаться то можно, но все значения равны нулю,
такое ощущение что TRect не создан....
значения Area я описываю в объектах классов, унаследованных от TBase.
в чем я не прав?
что можно сделать?
xrob вне форума Ответить с цитированием
Старый 17.05.2011, 17:26   #8
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

> что можно сделать?

показать исходник
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 17.05.2011, 17:48   #9
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию

исходник примерно такой:

type
// описываем абстрактный класс
TBase = class
FX:integer;
end;

// описываем конкретный класс
TTest = class(TBase);
FX:integer;
end;

var
// объявляем массив и переменную для класса
Items:array of TBase;
Test:TTest;


implementation

Test:=TTest.Create; // создаем объект класса
Test.FX:=20; // присваиваем значение (успешно)
Items[0]:=Test; // массив по-идее of TBase, но потомки TBase добавляются в него

// проблема вот в чем:
Items[0].FX = 0;

логически порассуждав, я пришел к выводу что поскольку у меня массив of TBase,
то и FX он пытается прочитать из класса TBase, а не из экзепляра в массиве
(тупо, не правда ли?)
я нашел выход в том чтобы создать функцию,
которая возвращает нужное значение.
объявляю ее в обоих классах:


TBase = class
FX:integer;
function GetFX:integer; virtual; abstract;
end;

// описываем конкретный класс
TTest = class(TBase);
FX:integer;
function GetFX:integer; override;
end;


function TTest.GetFX:integer;
begin
Result:=FX;
end;

и тогда
Items[0].GetFX = 20; =)

решение, конечно, громоздкое, но оно хотя бы работает...
xrob вне форума Ответить с цитированием
Старый 17.05.2011, 19:42   #10
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

а зачем объявлять одинаковые поля?
FX:integer; достаточно объявить только в TBase, остальные его просто унаследуют.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Разные пароли на разные диапазоны zenner Microsoft Office Excel 22 27.11.2010 01:25
Одна процедура вместо трёх. Wild_klas Помощь студентам 10 01.11.2010 22:30
Разные компиляторы - разные результаты Кипящий чайник Общие вопросы C/C++ 3 16.07.2010 14:54
Одна оконная процедура TGrey[WoLf] Win Api 6 22.06.2010 00:30
Одна процедура для всех Edit(ов) SoftKoc Общие вопросы Delphi 7 23.01.2010 13:44