Форум: "Компоненты";
Текущий архив: 2006.12.03;
Скачать: [xml.tar.bz2];
ВнизПерекрытие методов класса-предка Найти похожие ветки
← →
Yuri Btr © (2006-04-07 18:28) [0]Добрый день, у меня пока мало опыта в написании компонент,
подскажите возможно ли создав клас наследник (ну например от TRichEdit), перекрыть один из методов предка TRichEdit - TCustomRichEdit.
И туда же, возможно ли перекрыть PROTECTED методы компонента ?
Заранее спасибо.
← →
MBo © (2006-04-07 18:34) [1]Да
Да
;)
← →
Yuri Btr © (2006-04-07 18:39) [2]to MBo
Не сочтите за наглость, но не могли бы вы уточнить как именно можно в коде указать что нужно перекрывать например метод CreateParams, который находится у TCustomRichEdit, а не у TRichEdit, наследником которго является мой компонент.
Я так понимаю просто указанием override не обойдётся, при компиляции будет выдавать, что метод у непосредственного предка не найден (когда то так пытался делать)
← →
Юрий Зотов © (2006-04-07 23:18) [3]> Yuri Btr © (07.04.06 18:39) [2]
> Я так понимаю просто указанием override не обойдётся
Обойдется.
> будет выдавать, что метод у непосредственного предка не найден
Не будет.
> когда то так пытался делать
Видимо, все же не так. А как-то иначе, раз возникала ошибка.
PS
Человек, взявшийся за разработку компонента, должен достаточно хорошо знать ООП и его реализацию в Delphi, чтобы вопросов по азам наследования у него уже не возникало. Поэтому очень рекомендую начать все же с книг.
← →
Yuri Btr © (2006-04-07 23:35) [4]to Юрий Зотов © (07.04.06 23:18) [3]
Спасибо, уже пробую
К сожалению разработка компонентов для меня новое дело и мне понадобилось всего лишь незначительно изменить имеющийся компонент.
Если будет возможность куплю и книгу :)
← →
MBo © (2006-04-08 11:20) [5]Нет необходимости наследоваться именно от TRichEdit, можно от TCustomRichEdit - ведь custom-классы созданы именно для порождения наследников - они имеют всю функциональность, только свойства неопубликованы, так что в наследнике есть возможность выбрать, что публиковать.
Это никак не повлияет на волнующую тебя проблему, тем более, что её в описанном виде не существует (либо имеются ошибки другого рода)
← →
MBo © (2006-04-08 11:24) [6]пардон за орфогр. ошибку :(
← →
Yuri Btr © (2006-04-08 11:45) [7]to MBo © (08.04.06 11:20) [5]
Дело в том, что я не хочу заново создавать аналог TRichEdit со всей функциональностью, проще взять и унаследовать от TRichEdit все его возможности, добавив что то своё или изменив существующее. Поэтому у меня и встал вопрос об изменении методов TCustomRichEdit - "дальнего предка" моего компонента TRichEditv2
← →
Юрий Зотов © (2006-04-08 13:08) [8]> Yuri Btr © (08.04.06 11:45) [7]
Дружище, если бы Вы только знали, ЧТО Вы говорите. Купите книжку, точно не пожалеете. Ссылка на первой странице этого форума.
← →
MBo © (2006-04-08 13:31) [9]>Yuri Btr
Ещё раз повторю - это важно:
TRichEdit отличается от TCustomRichEdit только тем, что в нем уже имеющиеся свойства объявлены как published - никакого кода не добавлено, только изменена видимость свойств!
← →
Yuri Btr © (2006-04-08 17:25) [10]to MBo © (08.04.06 13:31) [9]
to Юрий Зотов © (08.04.06 13:08) [8]
Спасибо всем, уже пробую.
← →
GrayFace © (2006-04-09 10:16) [11]
> Юрий Зотов © (07.04.06 23:18) [3]
> Человек, взявшийся за разработку компонента, должен достаточно
> хорошо знать ООП и его реализацию в Delphi, чтобы вопросов
> по азам наследования у него уже не возникало. Поэтому очень
> рекомендую начать все же с книг.
Ну, в обратную сторону тоже неплохо - в процессе создания компонент узнать ООП и его реализацию в Дельфи.
А, кстати, можно ли вызвать inherited процедуру не непосредственного предка? (Например, TWinControl.CreateParams в данном случае) Хм, пока писал вопрос, понял как это сделать, только чуть-чуть не красиво. А есть ли прямая поддержка этого?
← →
Юрий Зотов © (2006-04-09 19:38) [12]> GrayFace © (09.04.06 10:16) [11]
1. Можно и так. Вообще, можно сначала разучить все партии фортепьяно из репертуара Большого театра, а уж потом нотную грамоту осваивать. В итоге тоже получится хороший музыкант, только это несколько труднее и дольше выйдет.
2. Тоже можно. Можно даже и не предка, а вообще любой виртуальный метод любого класса, одноименный с собственным (или унаследованным). Достаточно лишь временно подменить содержимое указателя на класс (первые 4 байта экземпляра). А прямой поддержки этому нет (по крайней мере, в Delphi) - видимо, потому, что такие фокусы все же нарушают принципы ООП.
← →
GrayFace © (2006-04-10 13:43) [13]> Юрий Зотов © (09.04.06 19:38) [12]
2. Тоже можно. Можно даже и не предка, а вообще любой виртуальный метод любого класса, одноименный с собственным (или унаследованным). Достаточно лишь временно подменить содержимое указателя на класс (первые 4 байта экземпляра).
Можно гораздо аккуратнее:type
TMyCreateParams = procedure(self:TObject; var Params: TCreateParams);
begin
TMyCreateParams(@TWinControl.CreateParams)(self, Params);
end;
А прямой поддержки этому нет (по крайней мере, в Delphi) - видимо, потому, что такие фокусы все же нарушают принципы ООП.
Почему нарушают?
← →
Юрий Зотов © (2006-04-10 22:32) [14]> GrayFace © (10.04.06 13:43) [13]
type
TForm1 = class(TForm)
protected
procedure CreateParams(var Params: TCreateParams); override;
end;
type
TMyCreateParams = procedure(Self: TObject; var Params: TCreateParams);
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
TMyCreateParams(@TWinControl.CreateParams)(Self, Params) // 29-я строка
end;
Результат компиляции:[Error] Unit1.pas(29): Undeclared identifier: "CreateParams".
Либо я что-то сделал не так, либо Вы сказали что-то не то.
← →
GrayFace © (2006-04-11 10:31) [15]Да, я думал, что он виден. Вот так работает:
type
TForm1 = class(TForm)
protected
procedure CreateParams(var Params: TCreateParams); override;
end;
type
TMyCreateParams = procedure(Self: TObject; var Params: TCreateParams);
TMyWinControl = class(TWinControl)
end;
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
TMyCreateParams(@TMyWinControl.CreateParams)(Self, Params);
end;
← →
Юрий Зотов © (2006-04-11 12:37) [16]> GrayFace © (11.04.06 10:31) [15]
> Вот так работает
Видимо, Вы хотели сказать "компилируется", а не "работает". Потому что оно и правда не работает: "Control Form1 has no parent window".
Правда, и вариант с подменой класса дает ту же самую ошибку. Что, в общем-то, в данном случае и естественно - не каждый метод можно безопасно вызывать с помощью таких трюков и CreateParams к таким методам просто не относится.
Вы спрашивали "Почему такие фокусы нарушают принципы ООП". Вот и пример, почему - потому что прямой вызов метода дальнего предка обходит цепочку вызовов "по последовательному наследству". В итоге отрабатывает не весь код, который должен отработать и может получиться неверный результат. Что мы в данном случае и имеем.
← →
GrayFace © (2006-04-11 18:36) [17]Юрий Зотов © (11.04.06 12:37) [16]
Видимо, Вы хотели сказать "компилируется", а не "работает". Потому что оно и правда не работает: "Control Form1 has no parent window".
Главное - что способ работает.
Юрий Зотов © (11.04.06 12:37) [16]
Правда, и вариант с подменой класса дает ту же самую ошибку. Что, в общем-то, в данном случае и естественно - не каждый метод можно безопасно вызывать с помощью таких трюков и CreateParams к таким методам просто не относится.
А, по-моему, любой. Т.е. метод вызовется и отработает как при "чистом" вызове. Не запускается, наверное, из-за того что действия TCustomForm.CreateParams не были выполнены.
Согласен, нарушение принципов ООП имеется.
← →
Юрий Зотов © (2006-04-11 18:40) [18]> GrayFace © (11.04.06 18:36) [17]
> Не запускается, наверное, из-за того что действия
> TCustomForm.CreateParams не были выполнены.
Сорри за самоцитату: "прямой вызов метода дальнего предка обходит цепочку вызовов "по последовательному наследству". В итоге отрабатывает не весь код, который должен отработать и может получиться неверный результат. Что мы в данном случае и имеем".
Страницы: 1 вся ветка
Форум: "Компоненты";
Текущий архив: 2006.12.03;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.048 c