Design question - Abstract, base, interfaces, ack!

R

Rachel Devons

All,

I'm struggling with an OOP concept. Let me try to define what I'm wanting by
using some classic examples.

Let's say that I have classes called Square & Circle that derive from class
Shape. Within class Shape, it has a method called Save to save the object to
disk. It's defined in Shape because the logic to save the shapes is uniform
across all shapes.
Furthermore, let's say I've defined an interface called IDraw that includes
a method called Draw.

Now, what I want to be able to do is use a factory pattern to produce Shape
objects. Something like:

Public Shape GetShape(int shapeID) {
if (shapeID==1)
return new Square;
else
return new Circle;
}

Obviously, that's oversimplified but hopefully you get the point. The idea
is that the factory will determine what type of Shape object to create. Now
I want to be able to call the Draw method on the Shape object as such:

Shape someShape=GetShape(shapeID);
someShape.Draw(); // Defined in each class that derives from Shape.
someShape.Save(); // Defined in Shape itself.

This is where I'm stumped. Unless I implement a stub Draw() method in the
Shape class, the compiler will complain that the Draw method doesn't exist.
I suppose if I implement a stub method, then at runtime the proper Draw
method would be called, right? But it seems kind of kludgy to have a Draw()
method implemented in Shape if in fact the classes that derive from Shape
will always have a Draw method and it's one of those methods that will
actually be called.

This makes me think that I'm just designing this wrong. How would I go
about designing this? Overall, I have a base class that can't be abstract
because it does have some common functionality that needs to be available to
all derived class. I have an interface that dictates what methods need to be
implemented. And I want to be able to call one of those methods on the base
class, although the base class isn't implementing the interface.

Confused....
 
R

Rodger Constandse

Hi,

You are allowed to have non-abstract methods in an abstract base class that can
be used/shared by all the derived classes. As long as you won't be instatiating
any Shape objects directly (like new Shape()), you could make Shape abstract.

For example,

public interface IDraw
{
void Draw();
}

public abstract class Shape : IDraw
{
// make abstract so that derived classes have to implement
public abstract void Draw();

public virtual void Save()
{
// common save implementation available to all Shapes that can be
// overriden by derived classes if required
}
}

public class Circle : Shape
{
public override void Draw()
{
// circle's Draw implementation
}
}

Shape s1 = new Circle();
s1.Draw();
s1.Save();

Hope this helps...
 
D

David Browne

Rachel Devons said:
All,

I'm struggling with an OOP concept. Let me try to define what I'm wanting
by using some classic examples.

Let's say that I have classes called Square & Circle that derive from
class Shape. Within class Shape, it has a method called Save to save the
object to disk. It's defined in Shape because the logic to save the shapes
is uniform across all shapes.
Furthermore, let's say I've defined an interface called IDraw that
includes a method called Draw.

Now, what I want to be able to do is use a factory pattern to produce
Shape objects. Something like:

Public Shape GetShape(int shapeID) {
if (shapeID==1)
return new Square;
else
return new Circle;
}

Obviously, that's oversimplified but hopefully you get the point. The idea
is that the factory will determine what type of Shape object to create.
Now I want to be able to call the Draw method on the Shape object as such:

Shape someShape=GetShape(shapeID);
someShape.Draw(); // Defined in each class that derives from Shape.
someShape.Save(); // Defined in Shape itself.

This is where I'm stumped. Unless I implement a stub Draw() method in the
Shape class, the compiler will complain that the Draw method doesn't
exist. I suppose if I implement a stub method, then at runtime the proper
Draw method would be called, right? But it seems kind of kludgy to have a
Draw() method implemented in Shape if in fact the classes that derive from
Shape will always have a Draw method and it's one of those methods that
will actually be called.

That's why you mark Shape.Draw as abstract. Then Square must implement Draw
to be a concrete Shape.
This makes me think that I'm just designing this wrong. How would I go
about designing this? Overall, I have a base class that can't be abstract
because it does have some common functionality that needs to be available
to all derived class.

Just because it's abstract doesn't mean it can't implement some methods. It
just means that it doesn't implement all its methods.


David
 
J

Jeff Louie

Rachel... Well you are in luck. I have written 24 chapters on OOP
written using
a IDrawable interface as a sample. There is code listing for a fully
funtional
GDI+ program that draws Circle, Squares and Triangles.

http://www.geocities.com/jeff_louie/OOP/oop19.htm

Here is a chapter that writes the shapes to disk.

http://www.geocities.com/jeff_louie/OOP/oop22.htm

Here is a chapter on dynamic type based class factories

http://www.geocities.com/jeff_louie/OOP/oop18.htm

Regards,
Jeff
This is where I'm stumped. Unless I implement a stub Draw() method in
the
Shape class, the compiler will complain that the Draw method doesn't
exist.
 
R

Rachel Devons

Thanks for all the input, everyone! This certainly gives me some ideas to
chew on.
 

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