Even if it could be done, it sure looks like bad practice.
I suggest you use a property that can be changed in runtime, to make your object's behavior change according to your needs.
Main Topics
Browse All TopicsI have two class TFirts and TSecond. TSecond inherits from TFirsts.
User can create an object of type Tfirst at runtime. I want allow the
user later on to turn this object into a TSecond type. Can I do it?
Should I create a new TSecond object and then copy all the TFirst
fields to the second one?
Thx
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
Well, if you have a lot of differences between TFirst and TSecond, it makes sense to not having a complicated TFirst object just in case a property 'Type' changes from typFirst to typSecond
I certainly would not mark this kind of work as 'not proper' or 'bad practice', it very much depends on the use case.
add a method or two like :
procedure TFirst.Assign(tf:TFirst); // Copy all TFirst fields from one instance to the other. Maybe override it in TSecond if you have some other initializations to make when TSecond get content from TFirst
constructor TSecond(tf:TFirst); // Will essentially call Assign
For those who are not yet sure that this is not a bad practice, here are the advantages :
- why reserving a lot of memory when you only need a few properties when the object is on a 'lower' state
- a property "Type" that could change in real-time would have to implement every aspect Assign does, but "flatening" the inheritance. Besides, it would assume that going from type1 to type2 and from type2 to type1 again is of little consequence. It might not be what is needed, and 2 classes (or more) can emphasize those (needed) aspects, and ease implementation
- the overhead of copying a few fields is not an argument, as it is not likely to happen often.
If it's done right, this kind of "upgrade" of objects can be very convenient and efficient
I forgot the main black point of this : You can't have many references to the object, otherwise it's going to be a nightmare to update all new pointers to the new upgraded object.
But that is not much of a problem because
a) it's always a bad idea to have multiple references to the same object, except for localized methods during a process, which is unavoidable.
b) the objects that needs this kind of subterfuge most certainly needs already to be gathered in a collection of some sort (TObjectList), and they are always accessed through this list. So there is just one place to update, and this can be done in single Constructor/Destructor :
until you don't call any specific methods of TMyObj1, this will not complain.
a cast does not transform your object, it just allow (trying) access your object as another. You have to be very sure that everything you do after with this casted object is allowed by the base object.
So, you will have no gain, and you risk having loads of trouble by confusing yourself.
say for clarity, you have a property in TMyObj1 that is not there in TMyBase :
TMyObj1 = class (TBase)
private
_Prop:Integer;
public
property Prop:integer read _Prop write _Prop;
end;
if in your code you do
Obj1 := TMyObj1(ObjBase); ?
Obj1.Prop:=10;
this will compile, but on the property setting you will have an access violation error : you try to read a memory zone that is outside the memory block pointed by your ObjBase object
I guess you are trying to build an electronic scheme editor, so you will have to handle a bunch of basic components, that can have a different number of pins or specific properties. So You might want to manage what kind of transformation is possible, and what properties can be salvaged from the older component to the new one.
Creating a supercomponent with all possible properties is probably the best way to throw yourself through the window in a few month, as you will maybe have to implement some "virtual testing" of these scheme, or some other complex operations. You have to have different classes, and you have also the need for ugrade, so....
no, really, what you have to do is implementing an UpgradeFrom virtual method in your base class, to manage all common fields and when needed override and/or overload it to manage different pairs of transformation (from TypeA to TypeB)
...robably the best way to throw yourself through the window in a few month
not good. :-)
no, really, what you have to do is implementing an UpgradeFrom virtual method in your base class, to manage all common fields and when needed override and/or overload it to manage different pairs of transformation (from TypeA to TypeB)
An object of typeB may have a method i.e. DoSomeTask (implemented using interface) which is not part of TypeA definition. The DSomeTask procedure collect some date and do some calculation as well in order to valorize the propreties of TypeB object. So, the user may want to create for instance a node of typeA and then later on turn it into TypeB without loosing previous values (the ones of the baseclass). So I will be glad if you may guide me step by step on how to implement this virtual method. I caught what you have suggested at 60% :-)) some code may be helpful.
thx
>> So, the user may want to create for instance a node of typeA and then later on turn it into TypeB
>> without loosing previous values (the ones of the baseclass)
Yep, that's the Assign principle
Let's say :
TBaseClass=class
private
_P1:Integer;
_P2:String;
_P3:TObjectList; // a container is tricky
public
procedure Assign(B:TBaseClass);
property P1:Integer read _P1;
...
end;
TNewClass=class(TBaseClass
private
_P4:Integer;
...
end;
procedure TBaseClass.Assign(B:TBaseC
Var
i:integer;
begin
_P1:=B._P1;
_P2:=B._P2;
// _P3:=B._P3; // Dangerous, P3 is a container. If you clear one, the other will be cleared. If you free one, the other will be invalid and raise exceptions
// correct way of doing it :
_P3.Clear;
for i:=0 to B._P3.Count-1 do
_P3.Add(B._P3[i]); // still dangerous with objects if P3 is a container that owns objects, Ok otherwise
// or something like :
_P3.Add( TBaseItem(B._P3[i]).Create
end;
You can call then
NewObject:=TNewClass.Creat
NewObject.Assign(OldObject
and do all in one pass in a new constructor for NewClass calling the Assign with an old object passed as parameter.
Business Accounts
Answer for Membership
by: Geert_GruwezPosted on 2009-11-03 at 12:22:04ID: 25733143
don't think so
can you show what you want ?
maybe there is a way