Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2004.08.01;
Скачать: [xml.tar.bz2];

Вниз

Наследование компонента...   Найти похожие ветки 

 
Rouse_ ©   (2004-07-13 21:27) [0]

Тема, конечно интересная, но по сути своей более подходит именно к потрепаться, так как я хочу обсудить технологию наследования неких компонентов (написания их более развитых вариантов).

Итак:
Как наследоваться от TButton все прекрасно понимают и как добавить к нему нукую новую функциональность тоже... но вот возник у меня вопрос:
К примеру возьмем компонент наподобие ServerSocket (ну я сам сетевик, поэтому это самая понятная лично для меня аналогия :)
Что он может иметь:
некий слушающий сокет
и "массив" (неважно как он там реализован, хотябы через коллекции) рабочих сокетов...
Т.е. имеем компонент который содержит в себе себя (сори за каламбур) и массив неких объектов.

Теперь ситуация:
Мы хотим развить данный компонент. Все довольно просто:
1. наследуемся от него.
2. обьявляем необходимые свойства, функции процедуры, переопределяем при необходимости
3. выводум нужную нам функциональность в public/published

а вот теперь сама загвоздка:
представьте что расширить нужно не него, а класс представляющий собой массив включенных в него элементов.

В приведеном выше примере им выступит конечный сокет.
К примеру он имеет некий набор событий-свойств, но мне нужно добавить к нему еще одно свойство (ну для простоты некий property Register: Boolean read FRegister write FRegister;)
и вот что тогда предстоит:

Предстоит практически полностью переписать главный компонент, только из-за того что у одной из его переменных (массива объектов) добавилось новое свойство?

Это не есть неудобно.

Или я не вижу очевидных вещей или раскажите мне как вы решаете данные ситуации...

Заранее спасибо :)


 
Rouse_ ©   (2004-07-13 21:31) [1]

> Это не есть неудобно.
Читать как "Это не есть удобно" :)
Сори :)


 
jack128 ©   (2004-07-13 22:06) [2]

Нечего не понял.
Саш, а можно пример не из сетей?
А то тут

> и "массив" (неважно как он там реализован, хотябы через
> коллекции) рабочих сокетов...


> представьте что расширить нужно не него, а класс представляющий
> собой массив включенных в него элементов.
то есть коллекцию? Но дальше

> В приведеном выше примере им выступит конечный сокет
кто есть конечный сокет? тот который > наподобие ServerSocket или тот, который > некий слушающий сокет или может один из >рабочих сокетов...

Можно какой нить пример, пусть не имеющий смысла, но на основе того же button"a , а не этого многоликого сокета? :-)


 
Style ©   (2004-07-13 22:15) [3]


> Rouse_ ©   (13.07.04 21:31) [1]


Саня, я тоже ничего не поняL :) Можеть тебе в отпуск уже пора?? :))


 
Ломброзо ©   (2004-07-13 22:16) [4]

В спецификации COM проблему предложено решать совместимостью на уровне интерфейсов. Пусть кокласс версии 1.0 реализует какой-то интерфейс. Если нужно расширить функционал, необходимо отнаследовать второй интерфейс от первого, и тоже выставить его наружу (кокласс версии 2.0). Клиент по выбору может работать с любым интерфейсом из двух, причём во избежание ошибок доступа проверку можно осуществлять либо на этапе компиляции, либо в Run-time (QueryInterface). В Delphi в общем-то примерно то же самое можно сделать при помощи обычного наследования, используя RTTI, только код будет пестреть всякими там is и as.


 
Григорьев Антон ©   (2004-07-13 22:17) [5]

Вообще, можно сделать это через метаклассы и виртуальные конструкторы. Пусть тип-контейнер имеет свойство указателя на класс, объекты которого он содержит. Породил наследника от содержащегося класса - меняй это свойство у контейнера. Правда, придётся каждый раз приводить типы, чтобы получить доступ к новым полям и методам внутреннего класса.


 
Слабак   (2004-07-13 22:27) [6]

А представьте такую ситуацию. Умирает ваш-дед миллионер, в завещании все деньги передает в разные там фонды, а про вас пишет что нибуть вроде: "А этому бездельнику я наследую компонент"
Я бы деда еще разок убил


 
Григорьев Антон ©   (2004-07-13 22:30) [7]


> Слабак   (13.07.04 22:27) [6]


А что-нибудь по делу сказать - никак?


 
Слабак   (2004-07-13 22:39) [8]


> Григорьев Антон


Было бы как - сказал бы ))
В программировании я слабак ))


 
Ломброзо ©   (2004-07-13 22:51) [9]

>Слабак   (13.07.04 22:39) [8]
То есть Вас сюда случайно занесло?


 
Mim1 ©   (2004-07-13 22:52) [10]

Rouse_ ©   (13.07.04 21:27)

А хорошо что вы про колекшены вспомнили, там ведь мы расширяем вложенные в него элементы.

Так же можно посмотреть чтото вроде TTreeView.OnCreateNodeClass.

Однако если разработчиком этого не предусмотрено будет тяжелее :(


 
Слабак   (2004-07-13 22:55) [11]


> Ломброзо


Иногда на этом сайте читаю ПОТРЕПАТЬСЯ. Тут смешные люди есть )))
Я надеюсь здесь залетных не выгоняють???


 
Ломброзо ©   (2004-07-13 22:59) [12]

Нет, залётные здесь сперва вьют гнездо, потом долго и громко щёлкают клювом, но в конце концов полюбившимся всем пернатых друзей отправляют в муфельную печь. Изучать изнутри.


 
Rouse_ ©   (2004-07-13 23:22) [13]

Хорошо, попробую обьяснить...
Посмотрите вот сюда: > [10] Mim1 ©   (13.07.04 22:52)
Именно, что я и имел ввиду...

Давайте построим тестовый компонент...
 TTestItem = class(TPersistent)
 private
   AProperty: Boolean;
   //BProperty: Boolean;
 public
   property A: Boolean read AProperty write AProperty;
   //property B: Boolean read BProperty write BProperty;
 end;

 TTestComponent = class(TComponent)
 private
   FTest: TTestItem;
   function GetTestItem: TTestItem;
 public
   property TestAProperty: Boolean read GetTestItem;
 end;

Изначально мы имеем доступ к TTestItem у каторого есть только property A, а вот захотелось мне его расширить чтобы не меняя TTestComponent  у TTestItem появилось закоментированное property B

Дело в том что компонент предок ничего не знает что я пытаюсь его расширить TTestItem до property В и поэтому вызов "TTestComponent.FTest.В " не пропустит сам компилятор

Так понятно? Или я все же неясно выражаюсь...


 
Rouse_ ©   (2004-07-13 23:28) [14]

Во, даже лучше пример придумал...
Представьте (на примере того же буттона) - у нее есть TFont. Так вот нам необходимо написать предок TButton с расширеным TFont (ну к примеру наш TFont будет иметь свойство градиентной заливки :)


 
Style ©   (2004-07-13 23:35) [15]


> (ну к примеру наш TFont будет иметь свойство градиентной
> заливки :)


Ну так наследуемся от TFont и добавляем свойства градиентной заливки. наследуемся от Баттона и меняем TFont.. и Paint?

Или тебе надоело все ручками писать ??


 
Rouse_ ©   (2004-07-14 00:07) [16]

> Ну так наследуемся от TFont и добавляем свойства градиентной
> заливки. наследуемся от Баттона и меняем TFont.. и Paint?
> > Или тебе надоело все ручками писать ??

Хе... примерный код плз ;)
ЗЫ: что ж ты думал я просто так тему завел? ;)


 
Cobalt ©   (2004-07-14 00:14) [17]

2 Rouse_ ©
Тут вспоминается Фаронов, ТП 7.0 и его пример с коллекцией и полиморфизмом, правда там в коллекцию добавлялись элементы "извне" коллекции.
А у тебя элементы создаются изнутри коллекции, так?


 
Rouse_ ©   (2004-07-14 00:26) [18]

Именно так...
В качестве еще более наглядного приера
http://www.delphikingdom.ru/asp/viewitem.asp?UrlItem=/helloworld/tcollection.htm

Представьте что:
TSpot = class(TCollectionItem)
private
 FCenterX: integer;
 FCenterY: integer;
 FColor: TColor;
public
 constructor Create(Collection: TCollection); override;
 function GetGuid: lpwUUID;
published
 property CenterX: integer read FCenterX write SetCenterX default 3;
 property CenterY: integer read FCenterY write SetCenterY default 3;
 property Color: TColor read FColor write SetColor default clBlack;
end;

(да, мы поимели новую функцию...)

Но дело то в том что если наследоваться от него то тогда придется переписать TSpotCollection = class(TCollection)
а после этого и сам TDappledShape = class(TShape)

Потому что они и понятия о ней не имеют и вообще в DCU находятся...


 
Rouse_ ©   (2004-07-14 00:34) [19]

> [2] jack128 ©   (13.07.04 22:06)
> [3] Style ©   (13.07.04 22:15)
Жень, Сереж... тут все очень просто...
Я забыл выделить главную фразу "расширить нужно не него, а класс представляющий собой массив включенных в него элементов" и этим ввел вас обоих в заблуждение...
Мои извинения...


 
Rouse_ ©   (2004-07-14 00:39) [20]

> Style ©  
Блин, чур меня, Петр Сергеевич, есессно :)))


 
Юрий Зотов ©   (2004-07-14 06:34) [21]

> Rouse_

Вот вариант решения с минимальной перепиской контейнера (насколько я понял, его и имел в виду Антон).

TMyBaseObject = class(...)
...
 constructor Create; virtual;
end;

TMyBaseObjectClass = class of TMyBaseObject;

TMyObject1 = class(TMyBaseObject)
...
 property A...;
end;

TMyObject2 = class(TMyBaseObject1)
...
 property B...;
end;

TMyContainer = class(...)
private
 FMyObject: TMyBaseObject;
protected
 class function GetMyObjectClass: TMyBaseObjectClass; virtual;
public
 constructor Create;
 ...
 property MyObject: TMyBaseObject...
end;

constructor TMyContainer.Create;
begin
 inherited;
 FMyObject := GetMyObjectClass.Create
end;

class function TMyContainer.GetMyObjectClass: TMyBaseObjectClass;
begin
 Result := TMyObject2
end;

Если надо изменить внутренний объект, в контейнере потребуется заместить всего один метод. А неудобство в том, что придется часто приводить тип:
TMyObject2(MyContainer.MyObject).B := ...


 
SPeller ©   (2004-07-14 07:29) [22]

Я думаю что всё очень просто и никаких проблем нет. Переписать класс-предок нужно будет только там, где он создаёт объект. Просто заставить его создавать не TMyClass1, а TMyClass2. В остальном коде предку будет абсолютно начхать на подмену. А в потомке для доступа к новой функциональности придётся кадый раз приводить тип, но чтобы не загромождать конструкциями as/is, можно просто TMyClass2(SomeProperty).XXX; Вот и всё.


 
SPeller ©   (2004-07-14 07:32) [23]

... Или  заводить переменную
sv: TMyClass2;
begin
  sv := TMyClass2(SomeProp);
  ...
И дальше работать уже с переменной sv.


 
SPeller ©   (2004-07-14 07:35) [24]


> Предстоит практически полностью переписать главный компонент,
> только из-за того что у одной из его переменных (массива
> объектов) добавилось новое свойство?

Зачем? Если вы измените дочерний компонент, то основному тоже будет начхать на новую функциональность, он просто не будет к ней обращаться и работать с тем что было. КОнечно, если основной компонент не в dcu.



Страницы: 1 вся ветка

Форум: "Потрепаться";
Текущий архив: 2004.08.01;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.035 c
3-1089027525
jenya_d
2004-07-05 15:38
2004.08.01
Утилиты администрирования MS SQL 2000


3-1089282948
Tempo
2004-07-08 14:35
2004.08.01
Как программно добавить данные в DBGrid?


14-1089700442
leonidus
2004-07-13 10:34
2004.08.01
Как MMS-сообщение из инета на телефон послат


1-1089991635
ko
2004-07-16 19:27
2004.08.01
color


14-1089396760
Mell
2004-07-09 22:12
2004.08.01
Кто нить знает хоть один адрес типа рамблер.ру русскими буквам





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