JScript .NET, Part IV: Inheritance

Protecting Methods from Overriding

When you define a class for other developers to use, there is always a chance that it will be extended. You need to adopt a defensive attitude, thinking how to protect your class from being corrupted by any derived class. One way is to label your classes and methods as final. Marking your class as final is trivial, but does not buy you much. In fact, it can be counter-beneficial. Your classes will not be reused by other team members, and you will not be contributing to the efficiency of the team as you might have done if you shared your classes. Marking selected functions as final is a more logical thing to do. In this way, you prevent people from overriding your implementation with the override modifier. You also prevent them from hiding your implementation with the hide modifier. So, whether your variable is of the base class or the derived class type, the only definition that rules is yours.

You cannot mark Interfaces and members of interfaces as final. You cannot combine the final modifier with the other inheritance modifier, abstract. You cannot combine the inheritance modifiers with the static modifier, either. By default, class members are neither final nor abstract, so overriding is the default. The following example demonstrates the usage of the final modifier. We begin as on the previous page, with definitions of a base class and a derived class:

Now, we define a variable, player1, of the derived class SecondBase, and we create it with the derived class default constructor:

var player1 : SecondBase = new SecondBase;

We then assign the new object to the variable player2, defined as of the base class type:

player2 : FirstBase = player1;

The following code:

player2.pitcher();
player2.hitter();

yields the next two lines:

I am a pitcher on first base
I am a hitter on second base

You can see that the pither() method is that of the base class, while the hitter() method is of the derived class. The base class method won because of its final modifier. The derived class method won because overriding is the default, and the base class function was not marked with final.