Of all the terms in programming I think
polymorphism is one of the coolest. While I cannnot include eclipse plug-in developer on my resume, I think being able to feature a cool term like polymorphism on my resume must be worth an extra $10 for my hourly rate!!!
Polymorphism is a common feature available in most object oriented programming languages such as java, c#, and VB.Net. Search the Domino designer help and you will not find any mentions of this term. In the limited coverage given to classes there are no hints as to polymorphism being available. And yet, it does seem that LotusScript can perform a limited amount of polymorphism.
If you are a LotusScript developer you may not have had the need to ever understand polymorphism (even if it did add $10 to your hourly rate). Consider a simple HR database such as the following:-
Class Person
' ...
End Class
Class Associate As Person
' ...
End Class
Class Contractor As Person
' ...
End Class
Class Manager As Associate
' ...
End Class
I could read a document from a Notes HR-related database and then assign it to a variable that is any one of the above classes. But what if I then wanted to start treating that variable like it belonged to one of the related classes? In C# this can be achieved using casting. It turns out that with LotusScript that the following code is possible:-
Dim Employee As Person
Set Employee = New Person(Doc)
Call Employee.Update()
Set Employee = New Manager(Doc)
Call Employee.Update()
In the above... The first time the Update method is invoked it will call the method defined in the Person class. The second time the update method is called it invokes the method defined in the Manager class (assuming it exists). There are some limitations with this approach. In particular, the properties/methods must all be defined in the base class.
The .Domino Framework provides 100+ custom classes defined so the need for polymorphism does arise periodically and will now be implemented using the above technique (for no other reason than to add polymorphism to my resume).
Comments (5)
I don't think this really qualifies as anything close to polymorphism ... In your last example setting Employee = New Manager(doc) creates a new instance of the manager class ... all references to the data previously defined would be lost ... for example (assuming the default value of the property "Rate" in the Person class is 100, and in manager class its 150)
Dim Employee as Person
Set Employee = New Person(doc)
Print Str$(Employee.Rate) ' Would Print 100
Employee.Rate = 125
Print Str$(Employee.Rate) ' Would Print 125
Set Employee = New Manager(doc)
Print Str$(Employee.Rate) ' Would Print 150
If it were true polymorphism, and I were able to cast Employee from
Person to Manager, this would happen:
Dim Employee as Person
Set Employee = New Person(doc)
Print Str$(Employee.Rate) ' Would Print 100
Employee.Rate = 125
Print Str$(Employee.Rate) ' Would Print 125
Print Str$((Employee as Manager).Rate) ' Would still Print
125
The line (Employee as Manager).Rate is an example of a cast ...
however because you aren't re-creating the object with a 'new' it
maintains its old value of 125 rather than resetting to 150.
Take for example that you had a bonus function that returned a
value of a dollar amount based on a factor of the position times
the base rate. Lets say for person, this is 10xBase Rate and for
Managers its 20xBase Rate ... you could then call the
following
Dim Employee as Person
Set Employee = New Person(doc)
Employee.Rate = 125
Print Str$(Employee.Rate) ' Would Print 125
Print Str$(Employee.Bonus) ' Would Print 1250
Print Str$((Employee as Manager).Bonus) ' Would Print 2500
You can also get tricky tricky where functions, etc can be called
from the class you've casted to that don't exist in the original
class, [as a general rule] but the objects have to be compatible
(ie derived from the same base class etc) ... So you cast a Pine
tree to a deciduous tree if they are both based on the same class
of tree .... and then you could potentially cast the pine tree into
lumber, etc, but you probably couldn't successfully cast a pine
tree into "tree house" for example because "tree house" is probably
rooted from a "structure" class, and probably contains "lumber"
elements in it...
@Jeremy.. I am not sure I would agree with your assertion that this is not "anything close to polymorphism". What I was hoping to demonstrate is that even with LotusScript is is possible to do some of the things commonly associated with polymorphism. With LotusScript we are most often extending a NotesDocument class and properties are typically implemented as fields in a NotesDocument. If I implemented your example as I would in the .Domino Framework (see code below) I believe I would get the results you are expecting even without saving the document to disk.
Class Person
Private iDocument As NotesDocument
Sub New ( Source As NotesDocument )
Set iDocument = Source
End Sub
Property Get EmployeeRate As String
If ( iDocument Is Nothing ) Then Exit Property
If ( iDocument. HasItem( "EmployeeRate" ) )
Then EmployeeRate$ = iDocument. GetItemValue( "EmployeeRate" ) ( 0)
End Property
Property Set EmployeeRate As String
If ( iDocument Is Nothing ) Then Exit Property
Call iDocument. ReplaceItemValue( "EmployeeRate" , EmployeeRate$ )
End Property
Sub Update( )
End Sub
End Class
Class Associate As Person
Sub New ( Doc As NotesDocument )
End Sub
End Class
Class Contractor As Person
Sub New ( Doc As NotesDocument )
End Sub
End Class
Class Manager As Associate
Sub New ( Doc As NotesDocument )
End Sub
End Class
No doubt that the seperation of logic based on differing "states" or "circumstances", in this case through the use of seperate classes is, or can be a good thing. However this closer to the start of a model-view-container than polymorphism. You are changing
the container by creating a new class to represent the logic of the
document. Polymorphism does not require reinitialization of the
object, it leaves the type of the original class intact, and most
importantly it allows you to transiently treat one type of object
as another. While the end result might be the same if you create
and reinitialize the object to the new type, perform the needed
operations, then reinitialize the object to the original class,
using a third class to martial the data between initializations (in
this case the notesdocument class), but that is really the exact
opposite of what polymorphism is. Like I said, I think you are
closer to am implentation of an MVC - which is a good practice,
it's just not polymorphism.
Whoops, and by MVC I mean model view controller, not container. Derrrrr...
Wikipedia has a nice example what Polymorphism is: http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming.
I use this all the time: Usually I define an abstract BaseClass of
something (in the same LS File as calling class) and then implement
the real class in an different LS file (-> "Illegal circular
use" problem).
You can also cast upwards:
dim manager as Manager
if person isa "MANAGER" then
set manager = person
call manager.executeStrategy()
else
call person.doWork()
end if
See also my take of an implementation of the adaptable pattern in
LS:
https://www.bleedyellow.com/blogs/jasc/entry/the_adapter_pattern_or_working_around_that_ls_has_no_interfaces46