Object Oriented Programming Language Features
This article describes the basic features involved in Object
Oriented Programming (OOP) languages in general and how they are
implemented in Visual Basic. It is by no means an all inclusive, definitive
reference but does serve to describe some of the typical features considered to
comprise an object oriented language. It may be a good starting point for less
experienced programmers.
Object oriented features are typically lumped into 2 categories. The first
includes the biggies: Polymorphism, Inheritance and
Encapsulation (PIE). The second includes other
features such as operation overloading, parameterized
constructors and class-level attributes and
operations.
Inheritance
Inheritance comes in two forms. Interface and
Implementation inheritance. Interface inheritance is available in
Visual Basic since VB6's introduction of the Implements
keyword. Implementation inheritance is available as of VB.NET with the
Inherits keyword.
The main difference between the two inheritances is that interface inheritance
should specify only a contract of desired behavior.
It should not allow any corresponding implementation code. It is up to other
classes, which realize that interface, to provide the implementation.
Implementation inheritance lets subclasses share common code and
attributes (properties). Also, implementation inheritance's ability
to declare an operation abstract enables it to act similar to interface
inheritance and force subclasses to implement the operation instead.
A VB.NET class can only enter into an implementation inheritance relationship
with one superclass (also called
base or ancestor class). However,
VB.NET, like VB6, lets that same class enter into as many interface inheritance
relationships as it chooses.
An example may help. Say you are developing an app in which the Store object
wants to ask an instance of the Stereo class to calculate availability
inventory. However, the Stereo class wants to borrow the functionality already
provided by its superclass, Product. The Store object might implement
such functionality like this:
Private myStereo as Stereo
Private Function getInventory() As Integer
getInventory = myStereo.calcInventory()
End Function
The real implementation of this behavior is in Product's calcInventory() method.
Because VB6 doesn't support implementation inheritance you need to put some
code in the Stereo class:
Implements Product
Private myProductObject as New Product
Private Function Product_calcInventory() As Integer
Product_calcInventory = myProductObject.calcInventory()
End Function
VB6 allows the interface, the Product class, to implement the actual behavior.
Stereo keeps an instance of Product (containment) then
asks that reference to do some work for it (delegation).
This type of interface inheritance is not a true interface because it
allows you to add code to Stereo to provide the actual behavior.
With VB.NET you can remove the containment and delegation code by using
implementation inheritance. For example, in the Stereo class:
Inherits Product
'
' any unique Stereo code
'
The Store class makes a calculation request similar to the way the Stereo class
makes this request, but Stereo carries out the work much differently in VB.NET.
The Stereo instance, myStereo, doesn't contain a calcInventory() method so VB
looks up its superclass, Product, and executes its calcInventory() procedure.
Implementation inheritance also allows you to override
superclass operations. An Items class might use this to provide its own
implementation of calcInventory() which would cancel out the behavior provided
by its Product superclass. For instance:
Overrides Function calcInventory() As Integer
'
' any unique Items code
'
End Function
All of the above may sound a bit confusing if you have not used inheritance in
the past. Take a second to reread the above and you will see that it is really
not that difficult. Interface inheritance tends to be a little harder to grasp
for some but, again, it is not that though of a concept.
When to Use Inheritance
Implementation inheritance allows you to reduce your code base drastically since
subclasses gain the methods of their superclass. This is a mixed blessing. If
you start with a poor design you will end up with code that is more difficult
than ever to debug and maintain.
Code and attributes once common in the superclass may not remain common as the
app's business needs evolve over time. Eventually many subclasses may end up
overriding the behavior of the superclass. Worse, the subclass may override the
superclass, do its own work, then call the same operation again on the
superclass. Believe me, I've seen it happen in other languages.
VB.NET requires you explicitly use the Overrides and Inherits keywords. Most
languages do not mandate this and are smart enough to know on their own. I
believe this is a good thing. It provides self documentation and instant visual
clue as to whether a method is overridden or not simplifying maintenance and
debugging.
Use Interface Inheritance When:
-
The base or superclass represents a generic facility such as a table lookup,
unique algorithm,...
-
The number of common operations is small.
-
The base class has few, if any, attributes.
-
Classes realizing the interface are diverse, with little or no common code.
Use Implementation Inheritance When:
-
The base class is an entity class (business or domain class) of primary
interest to the application (not a utility or control class).
-
The implementations are complex with a large number of operations.
-
Many operations and attributes are common across the subclasses.
Polymorphism
Polymorphism means many forms. It gives classes the ability to define the
same operation but provide unique implementations of that operation. In other
words, each of the class' methods is different. You can use polymorphism with
either interface or implementation inheritance.
Polymorphism is more than overriding a superclass's operations which is a small
part of polymorphism's power. For an operation to be polymorphic it must
implement an operation defined in an interface it implements or it must
implement an operation defined in a superclass. The superclass' operation is
typically abstract, which means it has no implementation code.
For example, you might encounter the getInformation() operation defined in
Product as abstract. If another object refers to either a Stereo or Items
object and wants to send it a message, it is best not to hard code that class
name:
Public Function getProductInfo(myProduct as Product) As Boolean
myProduct.getInformation()
End Function
The input parameter's data type is Product. VB is smart enough to know whether
the function is asking Stereo or Items to get its information.
Encapsulation
Encapsulation is also called information hiding and
ensures that no other class has knowledge about attributes and/or behavior
unless the class publishes them expressly.
VB lets you declare attributes and behaviors with the Private
keyword inside a class module. This hides them from the world outside of the
class. Conversly, if declared with the Public keyword
other objects can access those properties and methods yet know nothing of their
actual implementation.
Overloading
Overloading lets a function vary its behavior based on its input parameters.
VB.NET lets you have multiple functions with the same name but with different
input parameters. The language knows which version to execute based on what is
pased in. An example:
Overloads Function calcInventory() As Integer
'
' any code unique to this no parameter version.
'
End Function
Overloads Function calcInventory(dteDate as Date) As Integer
'
' code unique to this date driven version.
'
End Function
Overloads Function calcInventory(StartDate as Date, EndDate as Date) As Integer
'
' code unique to the date range version.
'
End Function
Shared Members
Sometimes you need to provide behavior on behalf of all objects in a particular
class and maintaining attributes that all instances of a class can have access
to. VB.NET uses shared members to resolves this
issue. Other languages call these feature static or
instance operations.
If the Product class needs to maintain an attribute and operation that are
available to all of its instances, you might implement the Product class like
this:
Shared TotalProductCount As Integer
Shared Function calcTotalProductCount As Integer
'
' get count of all products.
'
End Function
These attributes do not require an object instance to use them. In VB6 you can
create a variable in a .bas module that is acessible from all objects of a
given class. This achieves the same function but is not very object-oriented.
Glossary
|
Constructors
Constructors allow you to create an object and provide it with an initial set
of data so it can initialize properly. Without constructors, you create an
object, then need to all a separate method to initialize it. Two steps.
Encapsulation
Is data hiding. You can create a set of procedures or methods and properties
that form an interface. Other code can then use these methods with any
knowledge of the code within the methods. The procedures or methods you write
is called an implementation. The implementation is encapsulated within the
interface.
Inheritance
The concept that an object can gain the interface and actual behaviors
(implementation) of another object, then extend that interface or those
behaviors. Say you create a generic Product object that handles things common
to all your products. From it you may create specialized Perishable and
Non-Perishable objects. Both objects inherit the original Product object's
interface and behaviors but can extend or change some of those behaviors.
Initializers
An initializer allows you to declare a variable and assign it an initial value
all in one statement.
Object-Based
This loosely describes a language that interacts with objects easily and
directly.
Object-Oriented
Object oriented languages must support polymorphism, inheritance and
encapsulation (PIE).
Overloading
This allows you to declare multiple procedures with the same name in the same
scope each having different input parameter specifications. For instance, you
many define a function CreateTotal that totals the values in its array argument
and another CreateTotal function that takes 5 long arguments and returns their
sum. You call CreateTotal and pass it the proper parameters and the language
will know which version of the function to use.
Overriding
When using inheritance your new class gets all the methods from its parent or
super class. However you may want a different implementation for one of these
methods. You do so by overriding the original (inherited) method with your own
code. Your new code may even call the original method in the parent class.
Polymorphism
This is the ability to have two different objects of two different types both
implement the same method. It lets you write code that calls that method
regardless of which type of object is in use at the moment.
Shared Members
Otherwise know as class, static or instance members. Shared members are methods
or variables that are equally available to all instances of a class. Every
object that you create, based on a given class, shares these same variables and
routines.
User Interface Inheritance
Means you can create a VB form template then derive all your other forms from
this template. All other forms will inherit the look and code from the template
form. A change to the original form will propagate out to all the child forms.
|
|