- Abstraction in Visual Basic.NET
- Encapsulation in VB.NET
- Polymorphism in VB.NET
- Inheritance in VB.NET
- Interface-Based Programming
- Summary
Interface-Based Programming
Building component-based solutions has a number of unique problems and benefits. One of the key benefits is the ability to build applications on a piece-by-piece basis. The whole idea is to build software in the same way industry builds other productsinstead of a single monolithic system, systems are built as individual components.
This sounds great, but like so many great ideas, it's easier said than done, especially with earlier versions of Visual Basic. In theory, one should be able to take a component that does something and replace it with another component that does the same thing. But in most circumstances, this just doesn't happen.
Why? For performance reasons, developers prefer to use early binding to link components together at compile time. This causes components to be tightly coupled because in order to use early binding, components had to be explicitly referenced. This can lead to a nasty chain of recompilation, with a minor change to one component requiring recompilation of every component that depends on it, and all the components that depend on them, and so on.
With the introduction in VB 5 of the ability to keep the definition of an interface separate from the component that implements the interface, the need to tightly couple components in this way disappears. By referencing the interface rather than a class, an instance of any class that implements that interface can be created.
This technique allows a developer to continually change which component he actually uses. This is particularly important when a component and code using the component are being developed simultaneously. During the early stages of development, a simple implementation of a component can be used. Later, the completed implementation can be used, and finally some time later, a completely new implementation can be used to replace the initial implementation.
Interfaces make the complete software development process easier. They stress analysis and design, they make maintenance of applications easier, and they make deployment of applications easier. Interfaces are like car tires. How difficult would it be if you could only put one brand, style, and rating of tire on your car?
Changes to Interfaces in VB.NET
A few enhancements have been made to interfaces in Visual Basic.NET. The most important of these is that events can now be part of an interface. (In previous versions of VB, events were always late bound and never part of the interface.)
The mechanism for defining an interface has also been changed. In previous versions of VB, interfaces were created by coding a class or by using IDL. Listing 3.12 illustrates the new interface syntax with an event included in the interface. Although this is a very simple example, it is clear that interface definition in VB.NET follows the same clear Visual Basic syntax.
Listing 3.12 Define an Interface in VB.NET
Public Interface IEmployee Property FirstName() As String Property LastName() As String Function ChangeSalary(ByVal PercentageIncrease as Decimal) as Decimal Event Fired(ByVal ReasonCode as Integer) End Interface
Interfaces in VB.NET have a number of other enhancements, including inheritance. Once an interface has been created, it can be implemented by any .NET language. To implement an interface in VB.NET, you can use the method that was introduced in _VB 5 or the new method introduced in VB.NET. Listing 13 illustrates implementing an interface in VB 5 or VB 6. Listing 3.14 illustrates implementing an interface in VB.NET.
Listing 3.13 Implementing an Interface VB6 Style
Public Class Employee Implements IEmployee Private c_sFirstName as String Private c_sLastName as String Private c_dSalary as Decimal Private Property IEmployee_FirstName() as String Get IEmployee_FirstName = c_sFirstName End Get Set(ByVal Value as String) c_sFirstName = value End Set End Property Private Property IEmployee_LastName() as String Get IEmployee_LastName = c_sLastName End Get Set(ByVal Value as String) c_sLastName = value End Set End Property Private Function IEmployee_ChangeSalary _ (ByVal PercentageIncrease as Decimal) as Decimal Return c_dSalary * (PercentageIncrease / 100) End Function ' In this example I will not be implementing the event... 'Although this is required...The syntax is ' complex and for brevity will wait for the section on events End Class
VB.NET provides a cleaner, more flexible and easier to understand syntax for implementing interfaces. This can be seen in Listing 3.14.
Listing 3.14 Implementing an Interface VB.NET Style
Public Class Employee Implements IEmployee Private c_sFirstName as String Private c_sLastName as String Private c_dSalary as Decimal Public Property FirstNameofEmployee() as String _ Implements IEmployee.FirstName Get IEmployee_FirstName = c_sFirstName End Get Set(ByVal Value as String) c_sFirstName = value End Set End Property Public Property LastNameOfEmployee() as String _ Implements IEmployee.LastName Get IEmployee_LastName = c_sLastName End Get Set(ByVal Value as String) c_sLastName = value End Set End Property Private Function UpdateSalary(ByVal PercentageIncrease as Decimal) _ as Decimal Implements IEmployee.ChangeSalary Return c_dSalary * (PercentageIncrease / 100) End Function ' In this example I will not be implementing the event... 'Although this is required...The syntax is ' complex and for brevity will wait for the section on events End Class
The new style is far more flexible. For example, a class can implement more than one interface, and then use a single method to do the implementation of a method in both interfaces. Listings 3.15 and 3.16 show how this had to be implemented in VB 5 or _VB 6, whereas Listings 3.17 and 3.20 illustrate how to accomplish this in VB.NET.
Listing 3.15 Implementation of IEmployee in VB 5 or VB 6
Private Function IEmployee_ChangeSalary() As Decimal Return c_dSalary * (PercentageIncrease / 100) End Function
In Listing 3.16 we implement an additional interface in the same class and delegate to the previous interface functionality.
Listing 3.16 Implementation of IEmployee and IEmployee2 in VB 5 or _VB 6
Private Function IEmployee_ChangeSalary _ (ByVal PercentageIncrease as Decimal) As Decimal Return c_dSalary * (PercentageIncrease / 100) End Function Private Function IEmployee2_ChangeSalary _ (ByVal PercentageIncrease as Decimal) As Decimal Return IEmployee_ChangeSalary(PercentageIncrease) End Function
This isn't the case in VB.NET; you would simply change the existing methods implements clause (see Listing 3.17).
Listing 3.17 Implementation of IEmployee in VB.NET
Private Function UpdateSalary(ByVal PercentageToChange as Decimal) _ as Decimal Implements IEmployee.ChangeSalary Return c_dSalary * (PercentageToChange / 100) End Function
VB.NET allows us to add just a little bit of extra code to the function declaration to indicate that this function is also the implementation of Iemployee2.ChangeSalary (see Listing 3.18).
Listing 3.18 Implementation of IEmployee and IEmployee2 in VB.NET
Private Function UpdateSalary((ByVal PercentageToChange as Decimal) _ as Decimal Implements IEmployee.ChangeSalary, IEmployee2.ChangeSalary Return c_dSalary * (PercentageToChange / 100) End Function