views:

482

answers:

9

The C# spec, section 10.1.1.1, states:

An abstract class is permitted (but not required) to contain abstract members.

This allows me to create classes like this:

public abstract class A
{
    public void Main() 
    {
        // it's full of logic!
    }
}

Or even better:

public abstract class A
{
    public virtual void Main() { }
}

public abstract class B : A
{
    public override sealed void Main()
    {
        // it's full of logic!
    }
}

This is really a concrete class; it's only abstract in so far as one can't instantiate it. For example, if I wanted to execute the logic in B.Main() I would have to first get an instance of B, which is impossible.

If inheritors don't actually have to provide implementation, then why call it abstract?

Put another way, why does C# allow an abstract class with only concrete members?

I should mention that I am already familiar with the intended functionality of abstract types and members.

+9  A: 

The idea is to force the implementor to derive from the class as it is intended to provide only a basis for a presumably more specialized implementation. So the base class, while not having any abstract members may only contain core methods an properties that can be used as a basis for extension.

For example:

public abstract class FourLeggedAnimal
{

    public void Walk()
    {
        // most 4 legged animals walk the same (silly example, but it works)
    }

    public void Chew()
    {

    }
}

public class Dog : FourLeggedAnimal
{
    public void Bark()
    {
    }
}

public class Cat : FourLeggedAnimal
{
    public void Purr()
    {
    }
}
mjmarsh
One prominent example is System.Windows.Forms.ButtonBase, from which Button, CheckBox and RadioButton derive. It has no abstract members but lots of virtual methods and properties.
zinglon
This begs the question. If, as you say, "The idea is to force the implementor to drive from the class as it is intended to provide only a basis for a presumably more specialized implementation" then why doesn't it? This is the question I'm getting at in my OP.
fatcat1111
Not sure what the question is. It _does_ force the implementor to do just that, because as (in my example) calling the constructor (e.g. "new FourLeggedAnimal() )" will generate a compiler error.
mjmarsh
I think that your inline comment explains how this doesn't answer the question. "MOST 4 legged animals..." I would expect Walk and Chew to be virtual in this case.
Michael Petito
@zinglon: It's easy to see why you might have an abstract class with only virtual methods, as derived classes may specialize the implementation. Consider an abstract visitor class with only virtual methods. fatcat's question is when would you ever define an abstract class that does not allow an implementor to provide specialized implementation?
Michael Petito
@mjmarsh: I think the fatcat's point is that you can derive a new class, that adds absolutely nothing and can then be instantiated, which means that making the parent class abstract is meaningless.
nlawalker
@nlawalker @Michael: I know we are getting down to splitting hairs here but there may be cases where the abstract class' implementor does not know what services specialized implementations will want to add, and cannot therefore add any virtual methods/properties that may be of use to derived classes. I'm not sure if @zinglon's ButtonBase example meets this criteria, but I think it is a valid use case.
mjmarsh
I think that such abstract classes would only be useful if they are composed of properties and have methods that act on those properties. Otherwise, how would the abstract class's instance methods use the instance of the class? There is no state for it to access or modify, and they cannot be overridden by an implementor to use the state of the derived instance. Wouldn't they be as good as static then?
Michael Petito
I don't think this answers the question of the OP...
Charles
@fatcat1111: See my answer regarding the `Layer Supertype` pattern.
Charles
@mjmarsh: How would this be different to making the constructor `protected` and not using the `abstract` keyword?
Jeff Yates
@Jeff please see my comment on the question in response to Michael. You can subvert visibility with Dynamic Methods, and, indeed Reflection.Emit if you switch off visibility checks. You cannot subvert an abstract, however.
Andras Zoltan
@Andras: That's a good point.
Jeff Yates
A: 

The compiler does not prevent implementation-logic, but in your case I would simply omit abstract ?! BTW some methods could be implemented with { throw Exception("must inherit"); } and the compiler could not distinguish fully implemented classes and functions including only throw.

ralf.w.
Those methods that only raise exceptions should generally be abstract instead, but if not they should at least be virtual!
Michael Petito
your right. those methods should be virtual and abstract.
ralf.w.
+6  A: 

I think a slightly more accurate representation of your question would be: Why does C# allow an abstract class with only concrete members?

The answer: There's no good reason not to. Perhaps someone out there has some organizational structure where they like to have a noninstantiatable class at the top, even if a class below it just inherits and adds nothing. There's no good reason not to support that.

nlawalker
+1, The language designers decided to allow something instead of restrict something because they might not be able to think of all the uses which their users might someday think of.
tster
+9  A: 

Perhaps a good example is a common base class that provides shared properties and perhaps other members for derived classes, but does not represent a concrete object. For example:

public abstract class Pet
{
    public string Name{get;set;}
}

public class Dog : Pet
{
    public void Bark(){ ... }
}

All pets have names, but a pet itself is an abstract concept. An instance of a pet must be a dog or some other kind of animal.

The difference here is that instead of providing a method that should be overridden by implementors, the base class declares that all pets are composed of at least a Name property.

Michael Petito
+2  A: 

You said it -- because you can't instantiate it; it is meant to be a template only.

It is not "really a concrete class" if you declare it as abstract. That is available to you as a design choice.

That design choice may have to do with creating entities that are (at risk of mixing the terminology) abstractions of real-world objects, and with readability. You may want to declare parameters of type Car, but don't want objects to be declarable as Car -- you want every object of type Car to be instantiated as a Truck, Sedan, Coupe, or Roadster. The fact that Car doesn't require inheritors to add implementation does not detract from its value as an abstract version of its inheritors that cannot itself be instantiated.

Jay
+1  A: 

Abstract means providing an abstraction of behaviour. For example Vehicle is an abstract form. It doesn't have any real world instance, but we can say that Vehicle has accelerating behaviour. More specifically Ford Ikon is a vehicle, and Yamaha FZ is a vehicle. Both these have accelerating behaviour.

If you now make this in the class form. Vehicle is abstract class with Acceleration method. While you may/ may not provide any abstract method. But the business need is that Vehicle should not be instantiated. Hence you make it abstract. The other two classes - Ikon and FZ are concrete classes deriving from Vehicle class. These two will have their own properties and behaviours.

Chinjoo
A: 

Here's a potential reason:

Layer Supertype

It's not uncommon for all the objects in a layer to have methods you don't want to have duplicated throughout the system. You can move all of this behavior into a common Layer Supertype.

-- Martin Fowler

There's no reason to prevent having only concrete methods in an abstract class - it's just less common. The Layer Supertype is a case where this might make sense.

Charles
Is this any different from moving the methods from a common supertype to a static class?
Michael Petito
I think that were I to combine common methods I would either provide them in a static class or a base class. This doesn't really get to my question though: why allow an abstract class without any abstract members?
fatcat1111
…right, because there is no reason that a layer supertype need be declared abstract.
Jay
A: 

I see abstract classes serving two main purposes:

  • An incomplete class that must be specialized to provide some concrete service. Here, abstract members would be optional. The class would provide some services that the child classes can use and could define abstract members that it uses to provide its service, like in the Template Method Pattern. This type of abstract class is meant to create an inheritance hierarchy.

  • A class that only provides static utility methods. In this case, abstract members don't make sense at all. C# supports this notion with static classes, they are implicitly abstract and sealed. This can also be achieved with a sealed class with a private constructor.

Jordão
A: 

With regards to usage, using abstract on a class declaration but having no abstract members is the same as having the class public but using protected on its constructors. Both force the class to be derived in order for it to be instantiated.

However, as far as self-documenting code goes, by marking the class abstract it informs others that this class is never meant to be instantiated on its own, even if it has no virtual or abstract members. Whereas protecting the constructors makes no such assertion.

Jeff Yates