Some design issues about Inheritance

T

Tony Johansson

Hello!

Assune I have differentf FreightCars for example Tanker and Boxcar and
maybe some other shape of Freightcar.
FreightCars is a kind of vehicle pulled by a train.

If I would calculate for example the volume for these two I would first
create an abstract class called
Freightcar and then have Tanker and Boxcar as derived classes.

Now to my question: Assume the the most common Freight car is the Boxcar.
Is it better to have the method CalcVolume as an abstact method in the
baseclass and implement the CalcVolume in correct way in each derived class
?
Or put the CalcVolume for the Boxcar in the Base class and CalcVolume for
the Tanker in the tanker class ?

Next question is it any point not to let Freightcar be an abstract class?

I think it would be a clearer solution to let CalcVolume be an abstact
method in the Base class.

I would put general field like length,width,height,weight and freight car
number that every freightcar have in the base class.

The radius for the Tanker would be put in the derived Tanker class.

Does it sounds correct what I's saying here or do you have some comment ?

//Tony
 
P

Paul E Collins

Tony Johansson said:
Assume the the most common Freight car is the Boxcar. Is it better to
have the method CalcVolume as an abstact method in the baseclass and
implement the CalcVolume in correct way in each derived class ? Or put
the CalcVolume for the Boxcar in the Base class and CalcVolume for the
Tanker in the tanker class ?

If there is a default implementation for calculating volume, put that in
the base class and mark the method "virtual". Any deriving class can
either ignore the method (and use that default base implementation) or
replace it by rewriting the method and marking it "override".

Eq.
 
N

not_a_commie

I would say that the only way the volume function would fit in the
base class is if you didn't have to override it. In other words,
suppose all cars are either cylindrical or rectindrical. Then the
dimensions in combination with a flag for cylindrical would be
sufficient for a volume calculation and could be stored in the base
class. Another option would be to have a maximum weight and substance
density parameters. Those should apply to any type of train car. Then
you calculate the volume from that.
 
P

Peter Duniho

[...]
Now to my question: Assume the the most common Freight car is the Boxcar.
Is it better to have the method CalcVolume as an abstact method in the
baseclass and implement the CalcVolume in correct way in each derived
class
?
Or put the CalcVolume for the Boxcar in the Base class and CalcVolume for
the Tanker in the tanker class ?

Next question is it any point not to let Freightcar be an abstract class?

I think it would be a clearer solution to let CalcVolume be an abstact
method in the Base class.

I would put general field like length,width,height,weight and freight car
number that every freightcar have in the base class.

The radius for the Tanker would be put in the derived Tanker class.

Does it sounds correct what I's saying here or do you have some comment ?

General rule: only put implementation in an abstract base class that is
truly base implementation. That is, for your objects it's true that
either all subclasses will use that implementation, or it's a special case
for some subclass to override that implementation.

Applying that here, it comes down to the question of whether freight cars
generally have their volume calculated as rectangular volumes, or if box
cars are the only truly rectangular freight cars.

Given the wide variety of freight cars that exist, and given that at least
based on my non-expert experience it seems that many if not most freight
cars that are not box cars have irregular shapes that would require
overriding a base implementation (thinking here of grain cars, sand cars,
variations on the circular tanker theme, etc.), that the freight car class
would simply declare the calculation as an abstract member, requiring each
subclass to implement it.

As far as what the most common car is, I assume you're talking about
instances of the classes. But that's not really what's relevant with
respect to the class design. What's more relevant is what's most common
in each derived class, relative to the number of derived classes. If most
of your derived classes would reimplement the same volume calculation,
then that would suggest it makes sense to put that common calculation in
the base class.

That said, "rules are meant to be broken". Well, not really, but you
shouldn't feel that you have follow a rule blindly. In this case, since
you anticipate storing all of the data required to calculate a rectangular
volume in the base class already -- that is, you're not doing that just to
support the calculation of a default volume -- it could make sense as a
convenience to go ahead and include the default rectangular volume in the
base implementation, rather than making that calculation abstract. Even
if most derived classes won't use it.

In other words, I personally would just make it abstract, but I think
there's a valid argument for providing a default implementation.

As far as this question goes:
Next question is it any point not to let Freightcar be an abstract class?

If you wanted to treat the box car as a "generic freight car" class, then
you could just have the freight car implement all the box car behavior,
and not have an actual box car class. In that case, the freight car class
wouldn't be abstract and would include default implementations for any
virtual members. But if you never expect to instantiate an actual
instance of freight car, of course it's fine to make it abstract. Even
so, I wouldn't make it abstract unless you actually needed an abstract
member in it.

Pete
 
R

Richard Blewett

not_a_commie said:
I would say that the only way the volume function would fit in the
base class is if you didn't have to override it. In other words,
suppose all cars are either cylindrical or rectindrical. Then the
dimensions in combination with a flag for cylindrical would be
sufficient for a volume calculation and could be stored in the base
class. Another option would be to have a maximum weight and substance
density parameters. Those should apply to any type of train car. Then
you calculate the volume from that.

Of course that would be a huge pain if you actually waited to calculate the
volume of a train and process the entire freight in terms of Freightcars. It
is a perfectly reasonable solution to have the freight car with "knowledge"
of the necessity to be able to calculate the volume without being able to
supply a coherent implementation itself - thats, aftrr all, what abstract
methods are for.

Regards

Richard Blewett
DevelopMentor
http://www.dotnetconsult.co.uk/weblog2
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top