Overrides in VB.NET

Overrides is often confused with Overloads and Shadows.

Getty Images/Jetta Productions photo of a woman using computer
Woman sitting in front of a computer. Getty Images/Jetta Productions

This is one of a mini-series that covers the differences in Overloads, Shadows, and Overrides in VB.NET. This article covers Overrides. The articles that cover the others are here:

-> Overloads
-> Shadows

These techniques can be hugely confusing; there are a lot of combinations of these keywords and the underlying inheritance options. Microsoft's own documentation doesn't begin to do the topic justice and there is a lot of bad, or out of date information on the web.

The best advice to be sure that your program is coded correctly is, "Test, test, and test again." In this series, we'll look at them one at a time with emphasis on the differences.

Overrides

The thing that Shadows, Overloads, and Overrides all have in common is that they reuse the name of elements while changing what happens. Shadows and Overloads can operate both within the same class or when a class inherits another class. Overrides, however, can only be used in a derived class (sometimes called a child class) that inherits from a base class (sometimes called a parent class). And Overrides is the hammer; it lets you entirely replace a method (or a property) from a base class.

In the article about classes and the Shadows keyword (See: Shadows in VB.NET), a function was added to show that an inherited procedure could be referenced.


Public Class ProfessionalContact
 ' ... code not shown ...
 Public Function HashTheName(
 ByVal nm As String) As String
 Return nm.GetHashCode
 End Function
End Class

The code that instantiates a class derived from this one (CodedProfessionalContact in the example) can call this method because it's inherited.

In the example, I used the VB.NET GetHashCode method to keep the code simple and this returned a fairly useless result, the value -520086483. Suppose I wanted a different result returned instead but,

-> I can't change the base class. (Maybe all I have is compiled code from a vendor.)

... and ...

-> I can't change the calling code (Maybe there are a thousand copies and I can't update them.)

If I can update the derived class, then I can change the result returned. (For example, the code could be part of an updatable DLL.)

There is one problem. Because it's so comprehensive and powerful, you have to have permission from the base class to use Overrides. But well-designed code libraries provide it. (Your code libraries are all well designed, right?) For example, the Microsoft provided function we just used is overridable. Here's an example of the syntax.

Public Overridable Function GetHashCode As Integer

So that keyword has to be present in our example base class as well.


Public Overridable Function HashTheName(
 ByVal nm As String) As String

Overriding the method is now as simple as providing a new one with the Overrides keyword. Visual Studio again gives you a running start by filling in the code for you with AutoComplete. When you enter ...


Public Overrides Function HashTheName(

Visual Studio adds the rest of the code automatically as soon as you type the opening parenthesis, including the return statement which only calls the original function from the base class.

(If you're just adding something, this is usually a good thing to do after your new code executes anyway.)


Public Overrides Function HashTheName(
 nm As String) As String
 Return MyBase.HashTheName(nm)
End Function

In this case, however, I'm going to replace the method with something else equally useless just to illustrate how it's done: The VB.NET function that will reverse the string.


Public Overrides Function HashTheName(
 nm As String) As String
 Return Microsoft.VisualBasic.StrReverse(nm)
End Function

Now the calling code gets an entirely different result. (Compare with the result in the article about Shadows.)


ContactID: 246
BusinessName: Villain Defeaters, GmbH
Hash of the BusinessName: 
HbmG ,sretaefeD nialliV

You can override properties too. Suppose you decided that ContactID values greater than 123 would not be allowed and should default to 111.

You can just override the property and change it when the property is saved:


Private _ContactID As Integer
Public Overrides Property ContactID As Integer
 Get
 Return _ContactID
 End Get
 Set(ByVal value As Integer)
 If value > 123 Then
 _ContactID = 111
 Else
 _ContactID = value
 End If
 End Set
End Property

Then you get this result when a larger value is passed:


ContactID: 111
BusinessName: Damsel Rescuers, LTD

By the way, in the example code so far, integer values are doubled in the New subroutine (See the article on Shadows), so an integer of 123 is changed to 246 and then changed again to 111.

VB.NET gives you, even more, control by allowing a base class to specifically require or deny a derived class to override using the MustOverride and NotOverridable keywords in the base class. But both of these are used in fairly specific cases. First, NotOverridable.

Since the default for a public class is NotOverridable, why should you ever need to specify it? If you try it on the HashTheName function in the base class, you get a syntax error, but the text of the error message gives you a clue:

'NotOverridable' cannot be specified for methods that do not override another method.

The default for an overridden method is just the opposite: Overrideable. So if you want overriding to definitely stop there, you have to specify NotOverridable on that method. In our example code:


Public NotOverridable Overrides Function HashTheName( ...

Then if the class CodedProfessionalContact is, in turn, inherited ...


Public Class NotOverridableEx
 Inherits CodedProfessionalContact

... the function HashTheName cannot be overriden in that class. An element that cannot be overridden is sometimes called a sealed element.

A fundamental part of the .NET Foundation is to require that the purpose of every class is explicitly defined to remove all uncertainty. A problem in previous OOP languages has been called “the fragile base class.” This happens when a base class adds a new method with the same name as a method name in a subclass that inherits from a base class.

The programmer writing the subclass didn't plan on overriding the base class, but this is exactly what happens anyway. This has been known to result in the cry of the wounded programmer, "I didn't change anything, but my program crashed anyway." If there is a possibility that a class will be updated in the future and create this problem, declare it as NotOverridable.

MustOverride is most often used in what is called an Abstract Class. (In C#, the same thing uses the keyword Abstract!) This is a class that just provides a template and you're expected to fill it with your own code. Microsoft provides this example of one:


Public MustInherit Class WashingMachine
 Sub New()
 ' Code to instantiate the class goes here.
 End sub
 Public MustOverride Sub Wash
 Public MustOverride Sub Rinse (loadSize as Integer)
 Public MustOverride Function Spin (speed as Integer) as Long
End Class

To continue Microsoft's example, washing machines will do these things (Wash, Rinse and Spin) quite differently, so there's no advantage of defining the function in the base class. But there is an advantage in making sure that any class that inherits this one does define them. The solution: an abstract class.

If you need even more explanation about the differences between Overloads and Overrides, a completely different example is developed in a Quick Tip: Overloads Versus Overrides

VB.NET gives you even more control by allowing a base class to specifically require or deny a derived class to override using the MustOverride and NotOverridable keywords in the base class. But both of these are used in fairly specific cases. First, NotOverridable.

Since the default for a public class is NotOverridable, why should you ever need to specify it? If you try it on the HashTheName function in the base class, you get a syntax error, but the text of the error message gives you a clue:

'NotOverridable' cannot be specified for methods that do not override another method.

The default for an overridden method is just the opposite: Overrideable. So if you want overriding to definitely stop there, you have to specify NotOverridable on that method. In our example code:


Public NotOverridable Overrides Function HashTheName( ...

Then if the class CodedProfessionalContact is, in turn, inherited ...


Public Class NotOverridableEx
 Inherits CodedProfessionalContact

... the function HashTheName cannot be overriden in that class. An element that cannot be overridden is sometimes called a sealed element.

A fundamental part of the .NET Foundation is to require that the purpose of every class is explicitly defined to remove all uncertainty. A problem in previous OOP languages has been called “the fragile base class.” This happens when a base class adds a new method with the same name as a method name in a subclass that inherits from a base class.

The programmer writing the subclass didn't plan on overriding the base class, but this is exactly what happens anyway. This has been known to result in the cry of the wounded programmer, "I didn't change anything, but my program crashed anyway." If there is a possibility that a class will be updated in the future and create this problem, declare it as NotOverridable.

MustOverride is most often used in what is called an Abstract Class. (In C#, the same thing uses the keyword Abstract!) This is a class that just provides a template and you're expected to fill it with your own code. Microsoft provides this example of one:


Public MustInherit Class WashingMachine
 Sub New()
 ' Code to instantiate the class goes here.
 End sub
 Public MustOverride Sub Wash
 Public MustOverride Sub Rinse (loadSize as Integer)
 Public MustOverride Function Spin (speed as Integer) as Long
End Class

To continue Microsoft's example, washing machines will do these things (Wash, Rinse and Spin) quite differently, so there's no advantage of defining the function in the base class. But there is an advantage in making sure that any class that inherits this one does define them. The solution: an abstract class.

If you need even more explanation about the differences between Overloads and Overrides, a completely different example is developed in a Quick Tip: Overloads Versus Overrides