- Objects, Components, and COM
- Abstraction and Class Modeling
- Association Relationships
- One-to-One Relationships
- One-To-Many Relationships
- Class and Object Naming Conventions
- Component-Based Development
- Component-Based Development and COM
- COM-Definable Entities
- Component Coupling
Polymorphism is another standard feature of object-oriented programming. Fundamentally, polymorphism means the capability to define similar properties and methods on dissimilar classes. In essence, we define a common interface on a set of classes such that a calling application can use these classes with a standard set of conventions. Because this sounds complex, let us provide an example.
Suppose you are developing classes that must interact with a relational database. For each of these classes, there can be a standard set of methods to retrieve property values for an object instance from a database. We call this process of storing and retrieving property values object persistence, a topic we will discuss in detail in Chapter 5, "Distribution Considerations." We can illustrate an abstract definition of a couple of methods as follows:
Public Function RetrieveProperties(ObjectId As Long) As Variant ' code to retrieve the property values End Function Public Sub SetStateFromVariant(ObjectData As Variant) ' code to set the property values from ObjectData End Sub
For each class that is to follow this behavior, it must not only define, but also provide the implementation for these two methods. Suppose you have three such classesCClassOne, CClassTwo, and CClassThree. An application that creates and loads an object might implement polymorphic code in the following manner (see Listing 3.2).
Listing 3.2 The RetrieveObject Method
Public Function RetrieveObject(ClassType As Integer, ObjectId As Long) As Object Dim OClassAny As Object Dim ObjectData as Variant Select Case ClassType Case CLASS_TYPE_ONE Set OClassAny = New CClassOne Case CLASS_TYPE_TWO Set OClassAny = New CClassTwo Case CLASS_TYPE_THREE Set OClassAny = New CClassThree End Select ObjectData = OClassAny.RetrieveProperties(ObjectId) Call OClassAny.SetStateFromVariant(ObjectData) SetRetrieveObject = OClassAny End Function
In the preceding code example, we use a technique known as late binding, wherein Visual Basic performs type checking at runtime rather than at compile time. In this mode, we can declare a generic object (a variable type intrinsic to Visual Basic) to represent the instantiated object based on any of the three class definitions. We must assume that each of these classes defines and implements the RetrieveProperties and SetStateFromVariant methods as mandated by our polymorphic requirements. If the classes deviate from these conventions, a runtime error will occur. If the classes meet these requirements, we can simplify the coding of the object retrieval process into a single function call on the application. This not only leads to code that is easier to maintain over the life of the application, but also makes extending the application to support new class types much simpler.
The late binding technique of Visual Basic presents us with some concerns. Because late binding performs type checking at runtime, some errors might escape early testing or even propagate into the production application. Furthermore, late binding has a performance penalty because Visual Basic must go through a process known as runtime discovery with each object reference to determine the actual methods and properties available on the object. This said, we should scrutinize the use of late-binding approaches in the application wherever possible and choose alternative approaches. We will discuss several approaches to circumvent these issues when we discuss the framework components in Part II of the book.