Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Компоненты";
Текущий архив: 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.137 c
15-1163590192
Click
2006-11-15 14:29
2006.12.03
Снова вопрос "организации алгоритма"


2-1163766009
Grant
2006-11-17 15:20
2006.12.03
ODBC


4-1153117586
Russ
2006-07-17 10:26
2006.12.03
Как из сервиса узнать имя текущего пользователя


15-1163149860
Jolik
2006-11-10 12:11
2006.12.03
Стоит ли переходить на Delphi 2005?


15-1163148108
click
2006-11-10 11:41
2006.12.03
Куча будильников (напоминаний)





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский