You could take advantage of polymorphism. Define an abstract method in
the abstract base class which returns an instance of the abstract base
class. Then define a method in each concrete descendant which
instantiates a new instance of that type & copies all pertinent
elements to the new instance which is then returned.

Example:

function TAbstractClass.Clone : TAbstractClass; abstract; virtual;

function TConcreteClass1.Clone : TAbstractClass; override;
begin
  // TConcreteClass1 is aware of all interesting elements
  // and responsible for copying itself.
  Result := TConcreteClass1.Create;
  Result.ElementA := self.ElementA;
  Result.ElementB := self.ElementB;
  Result.ElementC := self.ElementC;
end;

function TConcreteClass2.Clone : TAbstractClass; override;
begin
  // TConcreteClass2 is aware of all interesting elements
  // and responsible for copying itself.
  Result := TConcreteClass2.Create;
  Result.ElementA := self.ElementA;
  Result.ElementE := self.ElementE;
  Result.ElementG := self.ElementG;
end;

Called like:
  // Compiler will know correct type.
  NewInstance := InstanceToCopy.Clone;

I hope I didn't make a stupid error, I typed it off the top of my head.

Hope this helps,

Roger C. Morgan II

--- In [email protected], Threetwosevensixseven
<[EMAIL PROTECTED]> wrote:
> I have a set of concrete classes which all inherit from an abstract  
> class. The client code which references them only knows them as  
> instances of the abstract class (I have a parameterised constructor  
> method, which is working fine).
> 
> The instances all contain elements which can contain primitive types  
> or else contain other elements. This follows the Composite design  
> pattern. The instances hide all details of these elements from the  
> client code.
> 
> The client code needs make a deep copy of an instance, which will  
> involve copying all the elements and their child elements, even  
> though the client doesn't know about these. (Ultimately, it also will  
> also need to 'add' two instances together to form a third instance,  
> which will involve 'adding' all the child elements together, but this  
> would follow the same principle as the deep copy).
> 
> To achieve this, I though it would be straightforward to pass the  
> instance to be copied to a class method in the abstract class. This  
> would determine the actual class and create a new instance of that  
> class. It should then be possible to pass the new instance to a  
> method in the passed instance. This method would copy its child  
> elements, and tell each of its children to do the same.   These copy  
> methods could all be protected methods of the abstract classes,  
> meaning they would be visible to the cloning class method and the  
> instances themselves, but not to the client code, which would only  
> need to call the public cloning class method.
> 
> I started to write it, as the code example below. Although the class  
> type is correctly detected, and the object is apparently created, the  
> constructors the abstract class or the concrete class are not called.  
> I have code in both of these, and both are being called if I create  
> the object in the client code using the parameterised constructor  
> method, or  'normally' using TConcreteClass.Create.
> 
> What am I doing wrong?
> 
> Thanks, Robin
> 
> ------------------------
> 
> interface
> 
> class function Clone(ConcreteInstance: TAbstractClass): TAbstractClass;
> 
> implementation
> 
> class function TAbstractClass.Clone(ConcreteInstance:
>    TAbstractClass): TAbstractClass;
> var
>    ConcreteClass: TClass;
> begin
> 
>    //Determine class of passed object
>    ConcreteClass := ConcreteInstance.ClassType;
> 
>    //Create a new object of the appropriate class -
>    //WHY are NEITHER constructors of concrete class
>    //NOR abstract class being called?!
>    Result := ConcreteClass.Create as TAbstractClass;
> 
>    //Tell passed object to deep copy its attributes to the
>    //newly created object, which will tell its children
>    //to do the same, and so on
>    ConcreteInstance.DeepCopy(Result);
> 
> end;




-----------------------------------------------------
Home page: http://groups.yahoo.com/group/delphi-en/
To unsubscribe: [EMAIL PROTECTED] 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/delphi-en/

<*> To unsubscribe from this group, send an email to:
    [EMAIL PROTECTED]

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 


Reply via email to