59

Just out of curiosity I tried overriding a abstract method in base class, and method the implementation abstract. As below:

public abstract class FirstAbstract
{
    public abstract void SomeMethod();
}

public abstract class SecondAbstract : FirstAbstract
{
    public abstract override void SomeMethod();
    //?? what sense does this make? no implementaion would anyway force the derived classes to implement abstract method?
}

Curious to know why C# compiler allows writing 'abstract override'. Isn't it redundant? Should be a compile time error to do something like this. Does it serve to some use-case?

Thanks for your interest.

Manish Basantani
  • 16,931
  • 22
  • 71
  • 103
  • I've used this feature a couple times. There are definitely use cases. – ChaosPandion Jan 18 '12 at 05:07
  • this should help: http://blogs.msdn.com/b/jmstall/archive/2005/08/07/abstract-override.aspx – S2S2 Jan 18 '12 at 05:08
  • why should something that is merely redundant cause a compile time error? – saus Jan 18 '12 at 05:42
  • 2
    @saus because some redundant things are silly enough that they suggest a mistake or misunderstanding and hence an error or at least a warning is appropriate. `public` on interface members would be an example. – Jon Hanna Jan 18 '12 at 16:34
  • I had a use case and was researching how to do this, which led me to this question. Your question answered my question, thanks! – palswim Aug 09 '16 at 23:28

7 Answers7

67

There's a useful example for this on Microsoft Docs - basically you can force a derived class to provide a new implementation for a method.

public class D
{
    public virtual void DoWork(int i)
    {
        // Original implementation.
    }
}

public abstract class E : D
{
    public abstract override void DoWork(int i);
}

public class F : E
{
    public override void DoWork(int i)
    {
        // New implementation.
    }
}

If a virtual method is declared abstract, it is still virtual to any class inheriting from the abstract class. A class inheriting an abstract method cannot access the original implementation of the method—in the previous example, DoWork on class F cannot call DoWork on class D. In this way, an abstract class can force derived classes to provide new method implementations for virtual methods.

svick
  • 236,525
  • 50
  • 385
  • 514
BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
  • 2
    What if I did something like `F ff = new F(); D dd = ff as D; dd.DoWork(0);`? Wouldn't that call `D`'s implementation? And if that's true, could I put inside `F`'s `DoWork(int i)`'s code something like `D dd = this as D; dd.DoWork(i);`? Would that call `D`'s implementation? – Blueriver Sep 27 '15 at 07:21
  • 4
    @Blueriver as with any virtual member, it would call the implementation of the actual object, so it that case it would call `F`'s implementation. – Jon Hanna Sep 13 '17 at 12:50
56

I find it really useful for ensuring proper ToString() implementation in derived classes. Let's say you have abstract base class, and you really want all derived classes to define meanigful ToString() implementation because you are actively using it. You can do it very elegantly with abstract override:

public abstract class Base
{
    public abstract override string ToString();
}

It is a clear signal to implementers that ToString() will be used in base class in some way (like writing output to user). Normally, they would not think about defining this override.

ghord
  • 13,260
  • 6
  • 44
  • 69
  • 1
    Upvoted. This is a great example that really belongs in this thread. Same example was also given in [an old answer elsewhere](http://stackoverflow.com/a/1769064/1336654) on Stack Overflow, just for comparison. – Jeppe Stig Nielsen Jul 27 '13 at 14:44
15

Interestingly enough, the Roslyn version of the C# compiler has an abstract override method in it, which I found odd enough to write an article about:

http://ericlippert.com/2011/02/07/strange-but-legal/

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • This makes sense if the base class’s member is `virtual`, but the compiler still allows it when the base member is `abstract`. Beyond guarding against the possibility that the base class’s member may one day be changed to be `virtual`, is that ever a valid pattern? – binki Oct 29 '22 at 01:59
6

Imagine that SecondAbstract is in the middle of a three-class hierarchy, and it wants to implement some abstract methods from its base FirstAbstract while leaving some other method X to be implemented from its child ThirdAbstract.

In this case, SecondAbstract is forced to decorate the method X with abstract since it does not want to provide an implementation; at the same time, it is forced to decorate it with override since it is not defining a new method X, but wants to move the responsibility of implementing X to its child. Hence, abstract override.

In general, the concepts modelled by abstract and override are orthogonal. The first forces derived classes to implement a method, while the second recognizes that a method is the same as specified on a base class and not a new one.

Therefore:

  • neither keyword: "simple" method
  • abstract only: derived class must implement
  • override only: implementation of method defined in base class
  • abstract override: derived class must implement a method defined in base class
Jon
  • 428,835
  • 81
  • 738
  • 806
  • 1
    But SecondAbstract is not required to include method X at all, since SecondAbstract is an abstract class. Adding X and decorating it as abstract override is equivalent to not including X at all, which is what the OP meant by redundant I guess. – saus Jan 18 '12 at 05:42
  • Does it mean that `SecondAbstract` is not satisfied with method X implementation of the base class? – Eranga Jan 18 '12 at 05:43
0

This design pattern is known as the Template Method pattern.

Wikipedia page on Template Methods

A simple, non-software example: There are a bunch of military units: tanks, jets, soldiers, battleships, etc. They all need to implement some common methods but they will implement them very differently:

  • Move()
  • Attack()
  • Retreat()
  • Rest()

etc...

noctonura
  • 12,763
  • 10
  • 52
  • 85
0

This is done because in child class you can not have abstract method with same name as in base class. override tells compiler that you are overriding the behavior of base class.

Hope this is what you are looking for.

Amar Palsapure
  • 9,590
  • 1
  • 27
  • 46
0

If you did not declare SomeMethod as abstract override in SecondAbstract, the compiler would expect that class to contain an implementation of the method. With abstract override it is clear that the implementation should be in a class derived from SecondAbstract and not in SecondAbstract itself.

Hope this helps...

Francois
  • 330
  • 1
  • 7