Code Re-use With Abstract Classes
- January 13th, 2012
- Write comment
An often overlooked feature of C# (and OO programming in general) is the use of abstract classes to maximise code re-use. Put simply, if you have code in related classes that is the same but needs to call implementation specific methods, you can probably use an abstract class to consolidate this code. Lets dive right in with a simple example.
This is production code that has been stripped back to highlight the use of abstraction. In my scenario I had a number of user controls that had to implement the same functionality to each display three different views. The initialisation code ran through the same method calls in each control but the implementations of the called methods were different. Enter the abstract class …
public abstract class ControlBase { public int ViewMode { get; set; } protected abstract void SetSaveButtonEnabled(); protected abstract void SetCollapsedView(); protected abstract void SetSummaryView(); protected abstract void SetExpandedView(); protected abstract void HideAll(); protected virtual void InitControl() { SetViewMode(); SetSaveButtonEnabled(); } protected virtual void SetViewMode() { HideAll(); switch (ViewMode) { case 1: SetCollapsedView(); break; case 2: SetSummaryView(); break; case 3: case 4: SetExpandedView(); break; } } } |
The InitView() and SetViewMode() methods are the same across all controls. Obviously the actual code to render the correct view is specific to the implementation of the control itself. So how does it work? Firstly, an abstract class can never be instantiated … it can only be inherited from. Any methods specific to the implementation are declared as abstract. In the abstract base class we know what the method signature should be but we can’t implement it at this level. Once the signature is provided and declared abstract we can call that method in the abstract class code as demonstrated in the SetViewMode() and InitControl() methods. At runtime this will result in the implementation of the method in the child class being called.
Our inherited class would look something like this …
public class Control1 : ControlBase { protected override void SetSaveButtonEnabled() { //control specific code here } protected override void SetCollapsedView() { //control specific code here } protected override void SetSummaryView() { //control specific code here } protected override void SetExpandedView() { //control specific code here } protected override void HideAll() { //control specific code here } } |
In the child class we override the abstract methods. Failing to override all the abstract methods on the base class will result in a compile time error unless your child class is also abstract.
That’s really all there is to it. By using this technique I saved having the InitControl() and SetViewMode() methods being implemented with the exact same code in all of my child controls. This would at best have been copy-paste coding which is horrible and to be avoided at all times. A bug in one of those methods would have resulted in needing to update all the implementations to fix it. Add the complexity of working in a team and another team member may not realise that the code is repeated in multiple controls. By using the abstract class there is only one implementation to maintain making maintenance much simpler while allowing a much more object oriented design.
More info on MSDN