However;
type
TMyComponent = class (TComponent)
private
FZoo: TZoo;
published
property Zoo: TZoo read FZoo write FZoo;
end;
var
Stream: TStream
MyComponent: TMyComponent;
begin
Stream := TMemoryStream.Create;
MyComponent := TMyComponent.Create (Nil);
MyComponent.Zoo.Add (TLion);
MyComponent.Zoo.Add (TSheep);
MyComponent.Zoo.Add (TCow);
Stream.WriteComponent (MyComponent);
Stream.Seek (0, 0);
MyComponent.Zoo.Clear;
Stream.ReadComponent (MyComponent);
TAnimal(MyComponent.Zoo.Items[0]).MakeNoise; // will raise an
EAbstractError exception.
This is because writing to a stream does not save the class type of the
collection items, and when read in, the code just calls TCollection.Add.
Regards,
Dennis.
> -----Original Message-----
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]]On
> Behalf Of Matt Powell
> Sent: Friday, 21 July 2000 17:23
> To: Multiple recipients of list delphi
> Subject: Re: [DUG]: TCollections...
>
>
> > Also, when I create my TCollection object, I pass the
> TCollectionItem
> > class I wish to use, is it possible to have different Item
> classes in one
> > collection? I was thinking of something like:
> (snip)
>
> Yes, it's eminently possible, and it's one of those wonderful
> OO things.
>
> The secret lies in not using the TCollection.Add method at all. If you
> examine the source for classes.pas, you'll find:
>
> function TCollection.Add: TCollectionItem;
> begin
> Result := FItemClass.Create(Self);
> end;
>
> All the work is done in the constructor of the item class.
> I've enclosed a
> small sample project to show you what I mean, but you
> basically don't have
> to change anything. Just pass in the class of the
> BaseItemClass thing when
> you create the collection, e.g.:
>
> with TAnotherCollectionItem.Create(MyCollection) do
> begin
> // Initialise values etc here
> end;
>
> > I was thinking I could dupe the behaviour of
> TCollection.Add and pass in
> > the class to create, but looking in the .dfm no classnames
> are mentioned
> > for the items.
>
> You can do that as well. Look at how I've done TZoo.AddAnimal. It's
> essentially the same as TCollection.Add, but it parameterises
> the type of
> the object. Yay.
>
> (I'm not quite sure what you mean by "looking in the .dfm no
> classnames are
> mentioned for the items"...?)
>
> I love OO. It gives me a warm feeling inside.
>
> - Matt
>
> 8<---
>
> program Project1;
>
> uses
> Classes,
> Dialogs;
>
> {$R *.RES}
>
> type
> TAnimal = class;
> TAnimalClass = class of TAnimal;
>
> TZoo = class(TCollection)
> procedure AgitateAnimals;
> function AddAnimal(AnimalType: TAnimalClass): TAnimal;
> end;
>
> TAnimal = class(TCollectionItem)
> public
> procedure MakeNoise; virtual; abstract;
> end;
>
> TLion = class(TAnimal)
> public
> procedure MakeNoise; override;
> end;
>
> TSheep = class(TAnimal)
> public
> procedure MakeNoise; override;
> end;
>
> TCow = class(TAnimal)
> public
> procedure MakeNoise; override;
> end;
>
> procedure TZoo.AgitateAnimals;
> var
> i: Integer;
> begin
> for i := 0 to Count - 1 do
> TAnimal(Items[i]).MakeNoise;
> end;
>
> function TZoo.AddAnimal(AnimalType: TAnimalClass): TAnimal;
> begin
> Result := AnimalType.Create(Self);
> end;
>
> procedure TLion.MakeNoise;
> begin
> ShowMessage('Roar!');
> end;
>
> procedure TSheep.MakeNoise;
> begin
> ShowMessage('Baa!');
> end;
>
> procedure TCow.MakeNoise;
> begin
> ShowMessage('Moo!');
> end;
>
> var
> CityZoo: TZoo;
>
> begin
> // make a zoo
> CityZoo := TZoo.Create(TAnimal);
>
> // add some animals
> TLion.Create(CityZoo);
> TSheep.Create(CityZoo);
> CityZoo.AddAnimal(TCow);
>
> // now stir them up a bit...
> CityZoo.AgitateAnimals;
>
> CityZoo.Free;
> end.
>
>
>
> --------------------------------------------------------------
> -------------
> New Zealand Delphi Users group - Delphi List -
> [EMAIL PROTECTED]
> Website: http://www.delphi.org.nz
>
---------------------------------------------------------------------------
New Zealand Delphi Users group - Delphi List - [EMAIL PROTECTED]
Website: http://www.delphi.org.nz