abstract, virtual and interfaces

S

Steve

I am designing a new class hierarchy and I've already run into a bit of a
bump in the road. I have this structure so far;
class CodeGen
class CodeGenHeader : CodeGen
class CodeGenProtocolHeader : CodeGenHeader


CodeGen is not an entirely abstract class, there are properties like
FileName, Date, etc that are shared with all class', however there are other
members that although they are shared with all the derived classes, need to
be implemented in the concrete class. For example, all the concrete objects
will have a void Generate() method, but each will be different.

I wanted to add public abstract void Generate() to my CodeGen class, but get
an error because the class itself isn't abstract. I found the docs a bit
confusing, they say that abstract can be used on class, property, delegate,
etc. But if the class itself must be abstract, what is the point of being
able to define it for other members?


Back to the design. So is this where I would want to use an interface? I
want something like this:

class CodeGen
{
protected string m_name;
public string Name{};

public abstract void Generate();
}

class CodeGenHeader : CodeGen
{
protected void GenerateIncludeBlock()
{
//...
}
}

class CodeGenProtocolHeader : CodeGenHeader
{
public void Generate()
{
GenerateIncludeBlock();
//....
}
}


Does that make sense?

Thanks,
Steve
 
B

Bruce Wood

When you declare a class as abstract, it means only that it contains
members that are not defined in the class and must be defined somewhere
down the class hierarchy, and as such you can never directly create an
instance of that (abstract) base class. It doesn't mean the class can't
define functionality that will be inherited by all derived classes. So,
you should write

abstract class CodeGen
{
protected string m_name;
public string Name{};

public abstract void Generate();
}

abstract class CodeGenHeader : CodeGen
{
protected void GenerateIncludeBlock()
{
//...
}
}

class CodeGenProtocolHeader : CodeGenHeader
{
public override void Generate()
{
GenerateIncludeBlock();
//....
}
}

The only hitch is that you can never say

CodeGen cg = new CodeGen();

or

CodeGenHeader cgh = new CodeGenHeader();

but then you probably wouldn't want to.
 
P

Peter Rilling

Unless I mis-understand your issue, you are confusing abstract with
inheritance and implementation. Classes can be inherited whether or not
they are marked as abstract. Classes that are marked as abstract cannot be
instantiated, but can still have implemented members. For instance, does
anything in your app ever need to call "new CodeGen()"? Does creating an
instance if CodeGen make any sense in the context of your application?

The reason that a class must be abstract if a member is also marked as such
is because it does not make much sense to allow the consumer to create an
instance of a class that does not implement everything. If this was
allowed, what would happen if the method was called that had not
implementation.

Interfaces are usually used for commands that are not associated with any
inheritance hierarchy, but rather general. Can I assume that Generate will
only be used with the CodeGen hierarchy? If so, then you can make this
abstract. If you have classes not related to CodeGen that also needs that
functionality, then you can make it an interface.

Hope this help.
 
S

Steve

Ah ha, Bruce, that makes a lot more sense to me. I re-read the doc after
your post and I get it now. Just got confused I guess.
Thanks for the post!
 
M

M. Genuini

A good technique that i use, during design, to decide when to use
classes, inheritance and all that stuff and instead to use interfaces
is to answer at the two question: "What it is it ?" and "What can do
?".
When i can answer to the first question then what i have is a class,
when i can answer to the second question i have an interface.
Example:
Triangle IS a Shape ----> Class
Square IS a Shape ----> Class
Point IS a Shape ------> Class

but what if i want implement fillable objects ?
a triangle can be filled, like a square, but not a point, but the point
continue to be a shape...so what ? here cames the interface, define an
IFillable interface and the game is done:

public class Shape......

public class Triangle : Shape, IFIllable

public class Square: Shape, IFIllable

public class Point: Shape

This is my 2cent help
 
S

Steve

That's a cool technique, thanks for telling me, I will try to use that for
the next set of classes :)
 

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