Thursday, June 07, 2007

abstract vs virtual

How's the confusion between whether to make functions in a class that is intended to be inherited, abstract or virtual.

I don't pretend to know the answer, so I "Googled". Here's a discussion I found...

It seems, while there are different opinions (how I'm not sure), that abtracts must be overrideen, but virtuals can be overridden.

Well, I have a base class (a form) doing a fair amount of standard work, and part of that standard work is to call two functions that must be overriddem by the child (descendant) form.

So, do I make them Virtual, or Abstract. Well it does in fact seem true, that if you are going to implement Abstract methods, the class must in fact be marked as abstract. But that's ok right? I can still mark my class as abstract, and implement the standard code I wish to, then mark the couple of methods I need the descendant to override, as abstract. (Big bonus here, the code won't comile if those methods aren't overridden, which is great because code in the base for call is, and relies on it.)

So then, I added a virtual method to my base form. It had to be filled in (i.e. it needed a body, unlike an abstract class, otherwise it won't comile). Good. Also, the code compiles fine when it is not overridden - I assume now, that unless it is overridden by a descendant form, the bahaviour defined in that base class, applies.

So here's my summary for now;
In a class intended as a base class...
  • Use private properties and methods where you want to contain functionality to the base class and hide it.
  • Use "virtual" methods if you want to define default behaviour that can be changed by descendants.
  • Use "abstract" methods if you want to force descendants to take some responsibility (if only it were this easy with our there's an idea for another post - until you're 18 years old, your "GetMoney() function is virtual - override it if you like but if not, it falls back to your parents, after that, it becomes abstract - you have to implement it yourself - some geek humour there). The catch with abstracts is, the entire class must then be marked as abstract and cannot be implement directly. This makes sense of course, because the very act of including an abstract method and calling it from code in your base class, means you are counting on it being inherited.

Thanks to this post for clearing it up in my head...

Another valid point is made here, that "base" classes can call virtual methods, and use the default behaviouir, but if they are overridden by a child object, the code in the original base class, will still reference the overridden virtual method (in the child object's code) unless the "new" keyword is used in the definition within the child object. (Some code examples maybe useful, but I don't have time, and there's heaps of them everywhere else - follow some of these links for just Google "abstract vs virtual".