Текущий архив: 2011.02.06;
Скачать: CL | DM;
Внизнаследование Найти похожие ветки
← →
Евгений07 (2010-11-15 11:42) [0]Доброго времени!
Не могу разобраться с наследованием форм.
Задача
Было несколько прог, состоящих из нескольких больших похожих форм
Решение
Разбить форму на 2 части типа
TVxod = в основном логика
ТVvod = в основном видимость
Выделить
Vvod0_N_T_; = форма родитель
Vvod4; = форма потомок, создан по inherited из формы родителя в проекте
Примечание:
логика и видимость переплетены, в логика использует видимость и наоборот
Облом:
если в родителе не создать переменные Vxod и Vvod, то
при работе родитель выдает ошибку, Vxod = nil,
Vvod = nil
если в родителе создать переменные Vxod и Vvod, то
при работе родитель работает правильно, а остальные
модули выдают ошибку: Vxod = nil, Vvod = nil
По логике переменные Vxod и Vvod надо создавать в потомках,
а родителей заставить в родительском коде с ними работать
unit Vvod00; //****************** общее
type
TVxod0 = class(TObject)
...
Constructor Create;
end;
end.
unit Vvod0_N_T_;//форма родитель ****
interface
uses Vvod00
type
TVxod = class(TVxod0)
...
Constructor Create;
end;
type
TVvod0_N_T = class(TForm)
procedure FormCreate(Sender: TObject);
...
end;
var
Vvod: TVvod0_N_T //
Vxod: TVxod;
implementation
procedure TVvod0_N_T1.FormCreate(Sender: TObject);
begin
...
Vxod := TVxod.Create;
end;
end.
unit Vvod4;//форма потомок****
interface
uses Vvod0_N_T_, Vvod00
type
TVxod1 = class(TVxod)
...
end;
type
TVvod0_N_T1 = class(TVvod0_N_T)
procedure FormCreate(Sender: TObject);
...
end;
var
Vvod: TVvod0_N_T1;
Vxod: TVxod1;
implementation
procedure TVvod0_N_T1.FormCreate(Sender: TObject);
begin
inherited;
...
Vxod := TVxod1.Create;
end;
end.
← →
clickmaker © (2010-11-15 11:53) [1]> TVvod0_N_T1
для начала стоит дать более осмысленные имена.
> логика и видимость переплетены, в логика использует видимость
> и наоборот
когда такое "сплетенье рук, сплетенье ног" неизбежно последуют проблемы, описанные ниже.
Надо как-то логику причесать
> TVxod = в основном логика
по большому счету логики в формах не должно быть - только ввод и отображение.
Попробуйте логику отделить ото всех форм в отдельный класс/модуль - сразу полегчает
← →
stas © (2010-11-15 11:55) [2]Непонятно зачем родителю класса работать с экземпляром класса потомка???
Вы чего-то напутали.
← →
Евгений07 (2010-11-15 12:49) [3]unit Vvod0_N_T_;//форма родитель ****
interface
uses Vvod00
type
TVxod = class(TVxod0)
...
Constructor Create;
end;
type
TVvod0_N_T = class(TForm)
procedure FormCreate(Sender: TObject);
...
end;
var
Vvod: TVvod0_N_T //
Vxod: TVxod; // зло здесь
implementation
procedure TVvod0_N_T1.FormCreate(Sender: TObject);
begin
...
Vxod := TVxod.Create;
end;
end.
← →
stas © (2010-11-15 13:44) [4]Евгений07 (15.11.10 12:49) [3]
Понятно. Но это в корне не правильно чтобы класс обращался к переменной типа своего потомка.
Если Вам нужно провести какие-то операции над классом, то он должен проводить их над своими же полями и т.д. Но никак над полями экземпляра класса.
← →
Евгений07 (2010-11-15 15:54) [5]Понятно. Но это в корне не правильно чтобы класс обращался к переменной типа своего потомка.
Если Вам нужно провести какие-то операции над классом, то он должен проводить их над своими же полями и т.д. Но никак над полями экземпляра класса.
Все правильно.
В другом модуле я обращаюсь к данным класса потомка
Дано: модули
unit Vvod00; //****************** общее
unit Vvod0_N_T_;//форма родитель ****
Vvod: TVvod0_N_T //
Vxod: TVxod;
unit Vvod4;//форма потомок****
Vvod: TVvod0_N_T1;
Vxod: TVxod1;
unit АААА;//форма
Действую: кнопка Vvod4;//форма потомок****
По трассировке ввод данных:
Vvod0_N_T_;//форма родитель ****
ввод данных:
Vvod: = есть
Vxod: = есть;
вызов метода АААА;//форма
АААА;//форма
Vxod: = nil
← →
Евгений07 (2010-11-15 15:55) [6]Понятно. Но это в корне не правильно чтобы класс обращался к переменной типа своего потомка.
Если Вам нужно провести какие-то операции над классом, то он должен проводить их над своими же полями и т.д. Но никак над полями экземпляра класса.
Все правильно.
В другом модуле я обращаюсь к данным класса потомка
Дано: модули
unit Vvod00; //****************** общее
unit Vvod0_N_T_;//форма родитель ****
Vvod: TVvod0_N_T //
Vxod: TVxod;
unit Vvod4;//форма потомок****
Vvod: TVvod0_N_T1;
Vxod: TVxod1;
unit АААА;//форма
Действую: кнопка Vvod4;//форма потомок****
По трассировке ввод данных:
Vvod0_N_T_;//форма родитель ****
ввод данных:
Vvod: = есть
Vxod: = есть;
вызов метода АААА;//форма
АААА;//форма
Vxod: = nil
← →
clickmaker © (2010-11-15 15:57) [7]> Vxod: = nil
Vxod := TVxod.Create; значит надо делать не в TVvod0_N_T1.FormCreate, а где-то в более глобальном месте, н-р секции initialization
← →
Евгений07 (2010-11-15 16:35) [8]Я сейчас проверить не могу, но кажется
var
Vxod: TVxod;
надо объявлять в классе форма родитель
unit Vvod0_N_T_;//форма родитель ****
interface
uses Vvod00
type
TVxod = class(TVxod0)
...
Constructor Create;
end;
type
TVvod0_N_T = class(TForm)
procedure FormCreate(Sender: TObject);
Vxod: TVxod; // = вставиь
...
end;
var
Vvod: TVvod0_N_T //
// Vxod: TVxod; // = убрать
← →
Jeer © (2010-11-15 17:02) [9]Вообще-то не зря придумали методы и свойства.
Вот со свойствами, а не с переменными, и надо работать.
← →
Евгений07 (2010-11-16 12:51) [10]Свойства это такой гемор при переделывании 5 прог
Хотелось бы менее кроваво отделаться. Пока я вижу возможность создать
форма родитель
форма потомок
без выделения данных и логики в отдельный класс
Минус = не могу выделить общую логику в отдельный юнит
← →
clickmaker © (2010-11-16 13:03) [11]> не могу выделить общую логику в отдельный юнит
это почему?
← →
Евгений07 (2010-11-16 13:36) [12]> не могу выделить общую логику в отдельный юнит
Логика не постоянная, идет с наследованием. Если ее определять в классах, то я должен задавать переменную объекта класса логики в каждой форме.
Получаются 2 разные переменные
Вариант 2. Глобальные переменные?? Возможна каша
Вариант 3. Переменные логики замесить с переменными формы, как было. Жалко выделенных в отдельный юнит обобщенных переменных и проц
← →
clickmaker © (2010-11-16 13:41) [13]> Получаются 2 разные переменные
>
> Вариант 2. Глобальные переменные?? Возможна каша
singleton?
← →
Евгений07 (2010-11-16 14:26) [14]>singleton?
Вариант 1 Выделить логику в отдельный класс, размазанный по 3 модулям:
TVxod0 = class(TObject) отдельный юнит
TVxod = class(TVxod0) модуль формы родителя
TVxod1 = class(TVxod) модуль формы потомка
Если задавать переменную объекта класса логики в каждой форме, то
получаются 2 разные переменные = ошибка
Вариант 2. Глобальные переменные?? Возможна каша
Вариант 3. Переменные логики замесить с переменными формы, как было. Жалко выделенных в отдельный юнит обобщенных переменных и проц
← →
Jeer © (2010-11-16 14:47) [15]
> Евгений07 (16.11.10 12:51) [10]
>
> Свойства это такой гемор при переделывании 5 прог
Понятно. Сначала месим кашу, потом расхлебываем.
Похвально.
Продолжайте.
← →
clickmaker © (2010-11-16 15:18) [16]> Сначала месим кашу, потом расхлебываем.
это "рефакторинг", как вы не понимаете... )
← →
Евгений07 (2010-11-16 15:26) [17]Как умученный вариант
Вариант 3 м. Переменные логики замесить с переменными формы, как было. Выделить в отдельный модуль с пустой формой обобщенные переменные и процЫ логики
TVxod0 = class(TForm) модуль обобщенных переменных и проц с пустой формой
TVxod = class(TVxod0) модуль формы родителя
TVxod1 = class(TVxod) модуль формы потомка
Что выбрать?
← →
Jeer © (2010-11-16 16:20) [18]
> процЫ логики
Это-то зачем в форму пихать ?
← →
Евгений07 (2010-11-16 16:27) [19]> процЫ логики
>Это-то зачем в форму пихать ?
уже отвечал:
Вариант 1 Выделить логику в отдельный класс, размазанный по 3 модулям:
TVxod0 = class(TObject) отдельный юнит
TVxod = class(TVxod0) модуль формы родителя
TVxod1 = class(TVxod) модуль формы потомка
Если задавать переменную объекта класса логики в каждой форме, то
получаются 2 разные переменные = ошибка
← →
clickmaker © (2010-11-16 16:38) [20]> Если задавать переменную объекта класса логики в каждой
> форме
а зачем?
← →
Евгений07 (2010-11-16 16:53) [21]> а зачем?
а как доступ из формы к логике
← →
clickmaker © (2010-11-16 16:58) [22]> как доступ из формы к логике
один раз создаем объект-singleton, пишем статический класс-обертку для методов, если надо, и вызываем, откуда хотим, не забыв только в uses прописать
← →
Евгений07 (2010-11-18 11:50) [23]один раз создаем объект-singleton, пишем статический класс-обертку для методов, если надо, и вызываем, откуда хотим, не забыв только в uses прописать
Спасибо clickmaker © (16.11.10 16:58) [22], по моим вопросам это лучшее решение. Но у меня вырисовалась отличная начальная форма, будет 3 уровня наследования. Всем спасибо, тема благополучно закрыта
Страницы: 1 вся ветка
Текущий архив: 2011.02.06;
Скачать: CL | DM;
Память: 0.51 MB
Время: 0.004 c