Here’s a scenario we’re all too familiar with: You’ve written some code, perhaps a collection of functions, which you want to reuse in another project. The key word here is reuse: write once, use many times. For years, VB developers were reusing code, even sharing it with others, with a very simple method: copying from one project and pasting it into another. The copy/paste approach to code reuse has never really worked because the code was never left untouched at its destination. In the process of reusing the original code in another project, we make changes to better accommodate the new project. In the process, we also improve the code. At some point, we decide that we should “return” the improved code to the original project and enhance it. Unfortunately, the improved code doesn’t always fit nicely into a different project. Some of the improvements break applications that used to work with the not-so-good code. If this has happened to you, imagine what a mess code sharing can be in a large environment with dozens of programmers. On a corporate level, this form of code reuse is a nightmare.
The promise of OOP is code reuse. The functionality you place into a class is there for your projects, and any other developer can access it as well. Inheritance is a technique for reusing and improving code without breaking the applications that use it. The idea is to export the code we want to reuse in a format that doesn’t allow editing. If more than two people can edit the same code (or even a single person is allowed to edit the same code in two different projects), any benefits of code reuse evaporate immediately. The code to be shared must be packaged as a DLL, which exposes all the functionality without the risk of being modified in a haphazard way. Only the original creator of the DLL can edit the code, and it’s likely that this person will make sure that the interface of the class doesn’t change. However, we should still be able to enhance the code in different projects. That’s where inheritance comes into the picture. Instead of getting a copy of the code, we inherit a class. The functionality of the class can’t change. The code in the DLL is well protected, and there’s no way to edit the executable code; it’s the class’s functionality we inherit.
However, it’s possible to add new functionality to the inherited code or even override some of the existing functionality. We can add new functionality to the code by adding new members to the existing classes. This doesn’t break any existing applications that use the original DLL. We can also override some of the functionality by creating a new method that replaces an existing one. Applications that use the original version of the DLL won’t see the new members because they work with the old DLL. Newer projects can use the enhanced functionality of the DLL. The current solution to the problem of code reuse is inheritance. It’s not a panacea, but it’s a step forward.
How to Apply Inheritance
Let me give a simple but quite practical example. A lot of functionality has been built into Windows itself, and we constantly reuse it in our applications. The various Windows Forms controls are a typical example. The functionality of the TextBox control, which we all take for granted, is packaged in a DLL (the System.Windows.Forms.TextBox class). Yet, many of us enhance the functionality of the TextBox control to address specific application requirements. Many developers add a few statements in the control’s Enter and Leave events to change the color of the TextBox control that has the focus. With VB 2008, it’s possible to write just two event handlers that react to these two events and control the background color of the TextBox with the focus. These two handlers handle the corresponding events of all TextBox controls on the form.
A better approach is to design a “new” TextBox control that incorporates all the functionality of the original TextBox control, and also changes its background color while it has the focus. The code that implements the TextBox control is hidden from us, but we can reuse it by building a new control that inherits from the TextBox control. As you will see in Chapter , ‘‘Building Custom Windows Controls,” this is not only possible, but almost trivial; we’ll build an enhanced TextBox control with a few lines of code. Actually, it’ll be more convincing if I show you the code right now, so here’s the code that implements an enhanced TextBox control, the FocusedTextBox control. (I copied from an example in Chapter “Building Custom Windows Controls”.):
As you understand, the two Color variables are properties of the control (implemented with the usual setters and getters), so that different applications can use different colors for the active TextBox control on the form.
With the Inherits statement, we include all the functionality of the original TextBox control without touching the control’s code. (The Inherits statement is stored in a different file from the rest of the code, but this a technicality I’ll address in the following chapter.) Any project that uses the FocusedTextBox control can take advantage of the extra functionality, yet all existing projects will continue to work with the original version of the control. We can easily upgrade a project to take advantage of the enhanced TextBox control by replacing all the instances of the TextBox control on a form with instances of the new control. Some projects may use the new control, yet not take advantage of the new functionality and leave the default colors — in which case the enhanced control behaves just like the original TextBox control.
Inheritance is simply the ability to create a new class based on an existing one. The existing class is the parent class, or base class. The new class is said to inherit the base class and is called a subclass, or derived class. The derived class inherits all the functionality of the base class and can add new members and replace existing ones. The replacement of existing members with other ones is called overriding.When you replace a member of the base class, you’re overriding it. Or, you can overload a method by providing multiple forms of the same method that accept different arguments.
To understand how useful inheritance is to team development, I’ll start with an example of extending an existing class, which is part of the Framework. As you can guess, I will inherit the functionality of an existing class, because I can’t touch the code of the Framework and introduce any improvements.