Change Object Type at Runtime

  • Thread starter Thread starter yohaas
  • Start date Start date
Y

yohaas

I'm trying to do something, not sure if it's possible or even if it
makes sense, but I figured I'd throw it out there.

I have a class OrderSummary that contains information about an order. I
then have two classes that inherit OrderSummary; K_OrderSummary and
M_OrderSummary which are specific types of orders. I will not know what
type of order it is until runtime so I want to create an object of type
OrderSummary. I only want to have to choose the type once for each
order (at runtime).

for example:

OrderSummary o;

//this will be done once, when the object is created, then the rest of
the code can just use type OrderSummary
if(type.Equals("k"){
o = new K_OrderSummary();
}
else{
o = new M_OrderSummary();
}

private void DoSomethingToOrder(OrderSummary order){
order.Something(); //this would call M_OrderSummary.Something() or
K_OrderSummary.Something() depending on what type of order it is.
}

Essentially, I want to use inheritance, but be able to declare the
object as the parent type, but use the child functions.

It would be similar to doing this:

Object o = new Form();
and then expect to be able to use o as if it were a Form object. The
declaration works, because Form inherits Object, but I of course do not
have access the the Form functions.

Make any sense?

Thanks,
Yohaas
 
Well, after that long winded questions - another two minutes of
serching yielded the answer: virtual.

It's easy, just make the function virtual in the base class, then
override it in the child class.


Yohaas
 
Makes perfect sense. What you want is something called "polymorphism,"
one of the basic concepts behing object oriented programming. If you
Google on "polymorphism" you'll find lots of information about it, in
general.

OrderSummary o;
if(type.Equals("k"){
o = new K_OrderSummary();
}
else{
o = new M_OrderSummary();
}

What you're really doing in the above code is implementing something
called a "Factory Method". I suggest going the whole distance and
making a method in OrderSummary that looks like this:

public static OrderSummary Factory(string summaryType)
{
if (summaryType == "k")
{
return new K_OrderSummary();
}
else
{
return new M_OrderSummary();
}
}

(and then improve it even further by making constants in OrderSummary
for "k" and "m").

Your Something() method you should implementing using an "override",
like this:

public abstract class OrderSummary
{
public abstract void Something();
}

public class K_OrderSummary : OrderSummary
{
public override void Something()
{
... do something for K order summary..
}
}

public class M_OrderSummary : OrderSummary
{
public override void Something()
{
... do something for M order summary..
}
}

then, when you have code that looks like this:

OrderSummary os = OrderSummary.Factory("k");
os.Something();

it will invoke the K_OrderSummary.Something() method polymorphically.
 
Bruce,
Thanks for the help - looks like a good solution too. I think I am
going to stick with the virtual methods though, since making abstract
methods in OrderSummary would prevent me from having non-abstract
methods. There are many common functions that I want to keep in
OrderSummary, and only override them when necessary.

Thanks again.
Yohaas
 
Whether OrderSummary should be abstract or not depends upon your
design. Does it make any sense to create an OrderSummary that is
neither a K_OrderSummary nor an M_OrderSummary? That is, can you say

OrderSummary os = new OrderSummary();

all by itself and it makes sense? If the answer is yes, then it should
_not_ be abstract. If the answer is "No, every order summary must be
either a K_OrderSummary or an M_OrderSummary" then it _should_ be
abstract.

Making a class abstract does _not_ stop you from adding non-abstract
methods to it. Declaring a class abstract means only two things:

1. The class has at least one method or property that is not defined in
the class (only declared), and must be defined by any child class that
you want to be able to instantiate (in your case, all child classes).
The class may have lots of non-abstract methods, but it has to have at
least one abstract method or class.

2. You cannot create an instance of the class itself, only instances of
any child classes that implement the stuff that you said was
"abstract".

Now, one reason why you might want Something() to not be abstract in
OrderSummary is if you want to provide a default implementation of it:
if it makes sense that there is a "generic" Something() that gets done
if a child class doesn't bother defining it. In that case you want to
declare it simply "virtual" and then override it in those child classes
that need behvaiour different from the default.
 
yohaas said:
Bruce,
Thanks for the help - looks like a good solution too. I think I am
going to stick with the virtual methods though, since making abstract
methods in OrderSummary would prevent me from having non-abstract
methods.
[Of course you can have non-abstract methods with abstract methods in
the abstract class, actually, it's a better approach if you don't want
the OrderSummery created by declaring it abstract. So people using your
class can only declare K_OrderSummery or M_OrderSummery, not OrderSummery).

John


There are many common functions that I want to keep in
 
Bruce and John,

Thanks to both of you - I had some misconceptions about abstract
classes. I will probably go back and make OrderSummary abstract, as
order will always be K or M.

Thanks again for the help.
Yohaas
 
Back
Top