Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I recently had to update an abstract base class on some OSS that I was using so that it was more testable by making them virtual (I could not use an interface as it combined two). This got me thinking whether I should mark all of the methods that I needed virtual, or if I should mark every public method/property virtual. I generally agree with Roy Osherove that every method should be made virtual, but I came across this article that got me thinking about whether this was necessary or not. I am going to limit this down to abstract classes for simplicity, however (whether all concrete public methods should be virtual is especially debatable, I am sure).

I could see where you might want to allow a sub-class to use a method, but not want it overriding the implementation. However, as long as you trust that Liskov's Substitution Principle will be followed, then why would you not allow it to be overriden? By marking it abstract, you are forcing a certain override anyway, so, it seems to me that all public methods inside of an abstract class should indeed be marked virtual.

However, I wanted to ask in case there was something I might not be thinking. Should all public methods within an abstract class be made virtual?

share|improve this question
    
This may help: stackoverflow.com/questions/391483/… –  Emmad Kareem Apr 15 '12 at 21:20
1  
Maybe you should look into why in C# the default is not virtual but in Java it is. The reason why would probably give you some insight into the answer. –  Daniel Little Apr 15 '12 at 23:07

5 Answers 5

up vote 4 down vote accepted

However, as long as you trust that Liskov's Substitution Principle will be followed, then why would you not allow it to be overriden?

For example, because I want the skeleton implementation of an algorithm to be fixed, and only allow specific parts to be (re)defined by subclasses. This is widely known as the Template Method pattern (emphasis below by me):

The template method thus manages the larger picture of task semantics, and more refined implementation details of selection and sequence of methods. This larger picture calls abstract and non-abstract methods for the task at hand. The non-abstract methods are completely controlled by the template method but the abstract methods, implemented in subclasses, provide the pattern's expressive power and degree of freedom. Some or all of the abstract methods can be specialized in a subclass, allowing the writer of the subclass to provide particular behavior with minimal modifications to the larger semantics. The template method (which is non-abstract) remains unchanged in this pattern, ensuring that the subordinate non-abstract methods and abstract methods are called in the originally-intended sequence.

Update

Some concrete examples of projects I have been working on:

  1. communicating with a legacy mainframe system via various "screens". Each screen has a bunch of fields, of fixed name, position and length, containing specific data bits. A request fills up certain fields with specific data. A response returns data in one or more other fields. Each transaction follows the same basic logic, but the details are different on every screen. We used Template Method in several different projects to implement the fixed skeleton of the screen handling logic, while allowing subclasses to define the screen-specific details.
  2. exporting / importing configuration data in DB tables to/from Excel files. Again, the basic schema of processing an Excel file and inserting/updating DB records, or dumping the records to Excel is the same for each table, but the details of each table are different. So Template Method is a very obvious choice to eliminate code duplications and make the code easier to understand and maintain.
  3. Generating PDF documents. Each document has the same structure, but their content is different each time, depending on lots of factors. Again, Template Method makes it easy to separate the fixed skeleton of the generation algorithm from the case-specific, changeable details. In fact. it even applies on multiple levels here, as the document consists of several sections, each of which consists of zero or more fields. Template Method is applied on 3 distinct levels here.

In the first two cases, the original legacy implementation used Strategy, resulting in lots of duplicated code, which of course over the years grew subtle differences here and there, contained lots of duplicated or slightly different bugs, and was very difficult to maintain. Refactoring to Template Method (and some other enhancements, like using Java annotations) reduced code size by about 40-70%.

These are only the most recent examples which come to my mind. I could cite more cases from almost every project I have been working on so far.

share|improve this answer
    
Simply quoting the GoF is not an answer. You'd need to give an actual reason to do such a thing. –  DeadMG Apr 15 '12 at 23:02
    
@DeadMG, I have been using Template Method regularly during my career, so I thought it was obvious that it is a very practical and useful pattern (as most of the GoF patterns are... these aren't theoretical academical exercises, but collected from real world experience). But apparently not everyone agrees with it... so I add a couple of concrete examples to my answer. –  Péter Török Apr 16 '12 at 8:33

Ask yourself what the use is of a non-virtual method in an abstract class. Such a method would have to have an implementation to make it useful. But if the class has an implementation, can it still be called an abstract class? Even if the language/compiler allows it, does it make sense? Personally, I don't think so. You would have a normal class with abstract methods that descendants are expected to implement.

My primary language is Delphi, not C#. In Delphi, if you mark a method abstract, you also have to mark it virtual or the compiler complains. Haven't followed the latest language changes too closely, but if abstract classes are in or would come to Delphi, I would expect the compiler to complain about any non-virtual methods, any private methods and about any method implementations for a class marked abstract at the class level.

share|improve this answer
2  
I think it makes perfect sense to have an abstract class that has some abstract methods, some virtual methods and some non-virtual methods. I think it always depends on what exactly do you want to do. –  svick Apr 15 '12 at 20:06
3  
First I will go over your C# q's. An abstract method in C# is implicitly virtual and cannot have an implementation. As to your first point, an abstract class in C# can, and should have an implementation of some sort (otherwise you should just use an interface). The point of a class being abstract is that it MUST be subclassed, however it contains logic that (theoretically) all subclasses will use. This cuts down on code duplication. What I am asking is whether any of those implementations should be closed off from being overriden (essentially saying the base way is the only way). –  Justin Pihony Apr 15 '12 at 20:06
    
@JustinPihony: thanks. In Delphi, when you mark a method abstract, the compiler will complain if you provide an implementation for it. Interesting how different languages implement concepts differently and thus create different expectations in their users. –  Marjan Venema Apr 16 '12 at 5:58
    
@svick: yes it does make perfect sense, I just wouldn't call it an abstract class, but a class with abstract methods... But I guess that may just be my interpretation. –  Marjan Venema Apr 16 '12 at 6:16
    
@MarjanVenema, but that's not terminology C# uses. If you mark any methods in a class abstract, you must also mark the whole class abstract. –  svick Apr 16 '12 at 12:03

It's perfectly reasonable, and sometimes desirable to have non-virtual methods in an abstract base class; just because it's an abstract class doesn't necessarily mean every part of it should be usable polymorphically.

For example, you might want to use the 'Non virtual polymorphism' idiom, whereby a function is called polymorphically from a non-virtual member function, in order to ensure that certain preconditions or postconditions are met before the virtual function is called

class MyAbstractBaseClass
{
protected:
    virtual void OverrideMe() = 0;
public:
    void CallMeFirst();

    void CallMe()
    {
        CallMeFirst();
        OverrideMe();
    }
};
share|improve this answer
    
I would argue that, as long as the overall behavior remains the same, then this could be made virtual. You could fill the pre/post conditions using a different implementation (database vs in-memory). Otherwise, it should be a private function? –  Justin Pihony Apr 15 '12 at 21:03

However, as long as you trust that Liskov's Substitution Principle will be followed, then >why would you not allow it to be overriden?

You don't make certain methods virtual because you don't believe this to be the case. Further, by making certain methods not virtual, you're signaling to inheritors what method(s) should be implemented.

Personally, I will often make method overloads that exist for convenience not virtual so that users of the class can have consistent defaults and implementers aren't even able to make the error of breaking that implied behavior.

share|improve this answer

It is enough for a class to contain ONE virtual method, in order for the class to become abstract. You might want to pay attention to which methods you want virtual and which not, according to the type of polymorphism you're planning to use.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.