473,473 Members | 1,480 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

OO, Inheritance and Queue

I have a queue that holds a list of objects with a common base type. As
a simple and contrived example, I have a common type of transportation
methods and derived classes (with there own individual methods which
extend the common base class) of Car, Bicycle and Plane:-

class Car : Transport { OpenWindow(); }
class Bicycle : Transport { RingBell(); }
class Plane : Transport { TakeNap(); }

I want to add each of these classes to the buffer. So I can enqueue
with:

Queue transportQueue;
transportQueue.Enqueue(MyCar);
transportQueue.Enqueue(MyBicycle);
transportQueue.Enqueue(MyPlane);

Now this is where I have got concerns. When I dequeue I do not know
what type has been dequeued.

Transport transportMethod;
transportMethod = (Transport) transportQueue.Dequeue();

When I dequeue, I know that it is a transport class but I do not know
if it is a Car, Bicycle or Plane.

I suppose I could use:
switch (typeof(transportMethod))
{
case Car:
break;
case Bicycle:
break;
case Plane:
break;
}

But this does not seem very Object Oriented and not very maintainable.
Is there a better way of doing this?

Aug 2 '06 #1
8 1250
The ideal would be if you can encapsulate the "do your thing" into a
suitable method that could be used via polymorphism - i.e. (the method name
is for illustration only):

abstract class Transport { abstract protected void
PerformPrimaryFunction();}
class Car : Transport { override protected void PerformPrimaryFunction() {
OpenWindow(); } }
class Bicycle : Transport { override protected void PerformPrimaryFunction()
{ RingBell(); } }
class Plane : Transport { override protected void PerformPrimaryFunction()
{ TakeNap(); } }

Then your queue handler can call .PerformPrimaryFunction() and it all "just
works"...

Marc
Aug 2 '06 #2
A better idea would be to not use inheritence in this case. Instead,
look into design patters, such as composition and strategy to achieve
the desired results.

Aug 2 '06 #3

There are 2 ways to solve this.

1, as previously mentioned.. is that you have either an Interface or
abstract class with the method.

public interface IVehicle
void DoSomething()

That would mean that Car, Bicycle and Plane implement this interface (or
abstract class), and write their own implmentations of DoSomething

#2 (which piggy backs off of #1)
If you have the Car Bicycle or Transport objects already, then you can look
at one of these design patterns.
Fascade
Adapter

http://www.dofactory.com/Patterns/Patterns.aspx

I'd probably go Adapter.

The key is that you should never/seldom/only once in a blue moon be writing
case statement checking for object type.
At least you were wise enough to ask, instead of plugging ahead.

...
<qu**********@yahoo.co.ukwrote in message
news:11*********************@m73g2000cwd.googlegro ups.com...
I have a queue that holds a list of objects with a common base type. As
a simple and contrived example, I have a common type of transportation
methods and derived classes (with there own individual methods which
extend the common base class) of Car, Bicycle and Plane:-

class Car : Transport { OpenWindow(); }
class Bicycle : Transport { RingBell(); }
class Plane : Transport { TakeNap(); }

I want to add each of these classes to the buffer. So I can enqueue
with:

Queue transportQueue;
transportQueue.Enqueue(MyCar);
transportQueue.Enqueue(MyBicycle);
transportQueue.Enqueue(MyPlane);

Now this is where I have got concerns. When I dequeue I do not know
what type has been dequeued.

Transport transportMethod;
transportMethod = (Transport) transportQueue.Dequeue();

When I dequeue, I know that it is a transport class but I do not know
if it is a Car, Bicycle or Plane.

I suppose I could use:
switch (typeof(transportMethod))
{
case Car:
break;
case Bicycle:
break;
case Plane:
break;
}

But this does not seem very Object Oriented and not very maintainable.
Is there a better way of doing this?

Aug 2 '06 #4
Marc Gravell wrote:
The ideal would be if you can encapsulate the "do your thing" into a
suitable method that could be used via polymorphism - i.e. (the method name
is for illustration only):

abstract class Transport { abstract protected void
PerformPrimaryFunction();}
class Car : Transport { override protected void PerformPrimaryFunction() {
OpenWindow(); } }
class Bicycle : Transport { override protected void PerformPrimaryFunction()
{ RingBell(); } }
class Plane : Transport { override protected void PerformPrimaryFunction()
{ TakeNap(); } }

Then your queue handler can call .PerformPrimaryFunction() and it all "just
works"...

Marc
In my example I was trying to create classes that had a commonality but
the derived classes implmented methods that had nothing in common. So
ther could not be found in the base class (PerformPrimaryFunction as
suggested).

Am I wrong but is it not the case that most derived classes will have
extra methods that only apply to this class and not to the base class?

Aug 2 '06 #5
I think one of my concerns is how the classes Car, Bicycle and Plane
are passed through the system. Should I have 3 separate overloaded
methods to deal with each class? Or shoudl I have a single class that
deals with the base Class Transport and somehow deal with determining
the actual class within the method?

I had a look at the Adapter and Facade patterns and I didn't really
pick up how they would help.

Also http://www.dofactory.com/Patterns/Pa...er.aspx#_self2
seemed to use w few switch statements.

sloan wrote:
There are 2 ways to solve this.

1, as previously mentioned.. is that you have either an Interface or
abstract class with the method.

public interface IVehicle
void DoSomething()

That would mean that Car, Bicycle and Plane implement this interface (or
abstract class), and write their own implmentations of DoSomething

#2 (which piggy backs off of #1)
If you have the Car Bicycle or Transport objects already, then you can look
at one of these design patterns.
Fascade
Adapter

http://www.dofactory.com/Patterns/Patterns.aspx

I'd probably go Adapter.

The key is that you should never/seldom/only once in a blue moon be writing
case statement checking for object type.
At least you were wise enough to ask, instead of plugging ahead.

..
<qu**********@yahoo.co.ukwrote in message
news:11*********************@m73g2000cwd.googlegro ups.com...
I have a queue that holds a list of objects with a common base type. As
a simple and contrived example, I have a common type of transportation
methods and derived classes (with there own individual methods which
extend the common base class) of Car, Bicycle and Plane:-

class Car : Transport { OpenWindow(); }
class Bicycle : Transport { RingBell(); }
class Plane : Transport { TakeNap(); }

I want to add each of these classes to the buffer. So I can enqueue
with:

Queue transportQueue;
transportQueue.Enqueue(MyCar);
transportQueue.Enqueue(MyBicycle);
transportQueue.Enqueue(MyPlane);

Now this is where I have got concerns. When I dequeue I do not know
what type has been dequeued.

Transport transportMethod;
transportMethod = (Transport) transportQueue.Dequeue();

When I dequeue, I know that it is a transport class but I do not know
if it is a Car, Bicycle or Plane.

I suppose I could use:
switch (typeof(transportMethod))
{
case Car:
break;
case Bicycle:
break;
case Plane:
break;
}

But this does not seem very Object Oriented and not very maintainable.
Is there a better way of doing this?
Aug 2 '06 #6
qu**********@yahoo.co.uk wrote:
I think one of my concerns is how the classes Car, Bicycle and Plane
are passed through the system. Should I have 3 separate overloaded
methods to deal with each class? Or shoudl I have a single class that
deals with the base Class Transport and somehow deal with determining
the actual class within the method?
I will use the first option.

I know you have three different methods in each class, but you can do it
that way, you can declare a virtual/abstract method in the Transport
class called
public virtual DoAnyThing();

And in car, you want to declare OpenWindow() as a private method, and
then you want to override this method.

public override DoAnyThing()
{
//Here, you can call the private defined method OpenWindow():
}
>>class Car : Transport { OpenWindow(); }
class Bicycle : Transport { RingBell(); }
class Plane : Transport { TakeNap(); }
>
I had a look at the Adapter and Facade patterns and I didn't really
pick up how they would help.

Also http://www.dofactory.com/Patterns/Pa...er.aspx#_self2
seemed to use w few switch statements.

sloan wrote:
>There are 2 ways to solve this.

1, as previously mentioned.. is that you have either an Interface or
abstract class with the method.

public interface IVehicle
void DoSomething()

That would mean that Car, Bicycle and Plane implement this interface (or
abstract class), and write their own implmentations of DoSomething

#2 (which piggy backs off of #1)
If you have the Car Bicycle or Transport objects already, then you can look
at one of these design patterns.
Fascade
Adapter

http://www.dofactory.com/Patterns/Patterns.aspx

I'd probably go Adapter.

The key is that you should never/seldom/only once in a blue moon be writing
case statement checking for object type.
At least you were wise enough to ask, instead of plugging ahead.

..
<qu**********@yahoo.co.ukwrote in message
news:11*********************@m73g2000cwd.googlegr oups.com...
>>I have a queue that holds a list of objects with a common base type. As
a simple and contrived example, I have a common type of transportation
methods and derived classes (with there own individual methods which
extend the common base class) of Car, Bicycle and Plane:-

class Car : Transport { OpenWindow(); }
class Bicycle : Transport { RingBell(); }
class Plane : Transport { TakeNap(); }

I want to add each of these classes to the buffer. So I can enqueue
with:

Queue transportQueue;
transportQueue.Enqueue(MyCar);
transportQueue.Enqueue(MyBicycle);
transportQueue.Enqueue(MyPlane);

Now this is where I have got concerns. When I dequeue I do not know
what type has been dequeued.

Transport transportMethod;
transportMethod = (Transport) transportQueue.Dequeue();

When I dequeue, I know that it is a transport class but I do not know
if it is a Car, Bicycle or Plane.

I suppose I could use:
switch (typeof(transportMethod))
{
case Car:
break;
case Bicycle:
break;
case Plane:
break;
}

But this does not seem very Object Oriented and not very maintainable.
Is there a better way of doing this?
Aug 3 '06 #7
I see two ways out here.

Depending on what you want to do in your switch statement.

If you want to call totally independent methods off each of your child
classes (i.e., if you are not after polymorphic behaviour), then
there's no difference here to having a queue<Transportversus just a
plain object[] transports.

The benefit of having a Transport in the collection is for
polymorphism.

If you are after polymorphism, then something like this is fun - I'll
reuse earlier examples mentioned.

class Transport { virtual PerformPrimaryFunction(); }
class Car : Transport {
void OpenWindow();
override PerformPrimaryFunction() {
OpenWindow();
base.PerformPrimaryFunction();
};
}
class Bicycle : Transport {
RingBell();
override PerformPrimaryFunction() {
RingBell();
base.PerformPrimaryFunction();
};
}
class Plane : Transport {
TakeNap();
override PerformPrimaryFunction() {
TakeNap();
base.PerformPrimaryFunction();
};
}

Then you can simplify your queue logic.
foreach(Transport t in queue)
t.PerformPrimaryFuncion();

jliu - johnliu.net

qu**********@yahoo.co.uk wrote:
Marc Gravell wrote:
The ideal would be if you can encapsulate the "do your thing" into a
suitable method that could be used via polymorphism - i.e. (the method name
is for illustration only):

abstract class Transport { abstract protected void
PerformPrimaryFunction();}
class Car : Transport { override protected void PerformPrimaryFunction() {
OpenWindow(); } }
class Bicycle : Transport { override protected void PerformPrimaryFunction()
{ RingBell(); } }
class Plane : Transport { override protected void PerformPrimaryFunction()
{ TakeNap(); } }

Then your queue handler can call .PerformPrimaryFunction() and it all "just
works"...

Marc

In my example I was trying to create classes that had a commonality but
the derived classes implmented methods that had nothing in common. So
ther could not be found in the base class (PerformPrimaryFunction as
suggested).

Am I wrong but is it not the case that most derived classes will have
extra methods that only apply to this class and not to the base class?
Aug 3 '06 #8

qu**********@yahoo.co.uk wrote:
I think one of my concerns is how the classes Car, Bicycle and Plane
are passed through the system. Should I have 3 separate overloaded
methods to deal with each class? Or shoudl I have a single class that
deals with the base Class Transport and somehow deal with determining
the actual class within the method?
The whole problem here is what do those methods do? What is it about
the Transport object that they need to know / deal with?

If a method needs to do something that is common to all Transport
objects (that is, declared in the Transport class), then there is no
problem. Just pass it a Transport and the method never has to know
which one it is.

If a method needs to do something that is common to some Transports but
not all Transports, then you have an interface scenario on your hands.
Remember: there is no law that says that just because a bunch of types
have a common base class, they can't also implement interfaces. For
example:

public class Car : Transport, IRequiresFuel { ... }

public class Plane : Transport, IRequiresFuel { ... }

public class Bicycle : Transport, IHumanPowered { ... }

etc. Now you're no longer asking, "Is this a plane or a car?" but
rather "Does this transport require fuel?" You can ask that question
easily like this:

IRequiresFuel fueledTransport = givenTransport as IRequiresFuel;

If a method needs to do something that is specific to exactly one
transport type (very rare), then you just have to cast to that exact
type.

Don't try to solve everything within the Transport base class. You're
allowed to use interfaces in addition to that. :-)

Aug 3 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Gandu | last post by:
Could some C++ guru please help me. I have a template based general linked list class that I want to inherit publicly to create a queue class. In the case of non-template inheritance, I can use:...
1
by: Tony Johansson | last post by:
Hello Experts! I reading a book called programming with design pattern revealed by Tomasz Muldner and here I read something that I think is wrong. Some background The following code shows how...
3
by: Eugene | last post by:
I'm trying to write a class which uses BinaryWriter as its base but allows for queuing of write requests Public Class QueuedBinaryWriter Inherits BinaryWriter I override all the Write methods...
22
by: Adam Clauss | last post by:
OK, I have class A defined as follows: class A { A(Queue<B> queue) { ... } } Now, I then have a subclass of both classes A and B. The subclass of A (SubA), more specifically is passed a...
4
by: Adam Clauss | last post by:
I ran into a problem a while back when attempting to convert existing .NET 1.1 based code to .NET 2.0 using Generic collections rather than Hashtable, ArrayList, etc. I ran into an issue because...
9
by: moleskyca1 | last post by:
I've ran into a problem with inheritance and STL containers. The code is too much to list, but here is the basic problem: #include <queue> using namespace std; class Base { public:
6
by: meLlamanJefe | last post by:
I am writing a queue object that will take different types of values. My approach is to have the std::queue take objects of a base class type while the user interacts with the queue using objects...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.