views:

132

answers:

3

In the following example, the class Derived implements the abstract method method from class Main. But I can't think of a reason to fill in the method body in the abstract Derived class' implementation. Surely I should only implement abstract methods within real classes.

So how can I avoid doing it? What else can I do?

abstract class Main
{
    public abstract void method();
}
abstract class Derived : Main
{
    public override void method()
    { 
    }
}

class RealClass : Derived
{

}
+4  A: 

If there's no implementation of method in Derived then you can just make Derived abstract as well:

abstract class Derived : Main
{
}

class RealClass : Derived
{
    public override void method() { ... }
}

EDIT: To clarify the comments - if there is no meaningful implementation of an abstract method in a subclass, then one does not need to be provided. This will however require that the derived class is itself abstract, and an implementation must be provided somewhere in the chain of descendant classes to some concrete subclass. I am not saying you should leave the implementation of method empty, as it is in the question, but rather you remove the override in Derived and mark the class abstract. This forces RealClass to provide an implementation (or itself be marked abstract).

Lee
I updated question. Already Derived was abstract in my example but i forgot it to write. But still VS2010 implement method class.
Freshblood
@Freshblood - You can just not provide any implementation of `method` in `Derived`. Only concrete classes have to provide implementations of all abstract members (directly or indirectly via their parent classes).
Lee
@Lee - So best thing to do is leave empty method body in Derived classes ? If method return a value,we have to return null or value for it so this is not good design. I am looking for better one.
Freshblood
@Freshblood - Any abstract method will have to be implemented somewhere for some concrete class (either in the class itself or some ancestor). I'm not saying you should leave `method` empty in Derived, but rather you should remove any reference to it altogether, which will require some subclass to implement it.
Lee
The key is to *omit* virtual methods that you don't want to implement. IntelliSense gets a bit gumpy here.
Hans Passant
+5  A: 

Usually if someone has specified that an abstract class has an abstract method, it's either because that class depends on that method for some of what it does, or it's because it's part of an expected API that it wouldn't make sense for the parent class to implement at this time. In either case, there must be an implementation once you get to a non-abstract implementation of the class.

Note also that if you are implementing an interface, you are required to state how that interface will be implemented, even if you just call the member abstract and pass the responsibility onto the subclass

public interface IPet {string GetNoise(); int CountLegs(); void Walk();}
public abstract class Pet : IPet
{
    public string Name {get; set;}
    public abstract string GetNoise(); // These must be here
    public abstract int CountLegs();
    public abstract void Walk();
}

When it comes to implementing the sub-class, you have a few choices depending on the circumstances. If your implementation is itself an abstract class, you shouldn't need to implement the abstract method.

public abstract class Quadruped : Pet
{
    public int CountLegs () { return 4; }
}

If your implementation is non-abstract, but the standard reason for the method in question really doesn't apply in your circumstance, you can do a no-op method (in the case of void methods), or return some dummy value, or even throw a NotImplementedException to indicate that the method should never have been called in the first place.

public class Fish : Pet
{
    public string GetNoise() {return "";} // dummy value: fish don't make noise
    public int CountLegs() {return 0;}
    public void Walk() {} // No-op
    // public void Walk() { throw new NotImplementedException("Fish can't walk"); }
}

Does that answer your question?

StriplingWarrior
+1, good answer. Strictly speaking, I think the `CountLegs` method in `Quadruped` should be sealed, or anyone will be able to create a quadruped with 3 legs ;)
Thomas Levesque
Nice answer. Yes it is answer of question. Using interface help to overcome that problem.
Freshblood
Another solution can be that just define Main method as virtual and just fill inside it for one of real class so i will not need to implement it on child abstract classes.
Freshblood
@Thomas: Why? Ever seen a three-legged dog? A dog loosing a leg may not be the "standard" fulfillment for a quadruped class contract, but a three legged-dog is still a quadruped and would need a different gate/walk from an intact four-legged one. Animation and CGI come to mind for this kind of situation...
Marjan Venema
StriplingWarrior
@Marjan, good point ;)
Thomas Levesque
A: 

All non-abstract descendant classes must provide concrete implementations of abstract methods. If you don't provide an implementation, then it's impossible to call that method.

If some concrete classes don't have an obvious proper implementation of a abstract method then your object design is incorrect. Maybe you should have an abstract class with some abstract methods (but not all). That class could have an both an abstract descendant and some concrete descendants.

Donnie