Finally, the final of the 4 posts on object-oriented principles forthose of you just coming to .Net from non-OOP languages. Data Abstraction, Encapsulation and Inheritance we have already discussed. Now we will talk about polymorphism.
Polymorphism means one name, many forms. Polymorphismmanifests itself by having multiple methods all with the same name, butslighty different functionality. Updated statement: Polymorphism can becoupled with inheritance, but inheritance is not a requirement to gainpolymorphic behaviors. Because of this, it can be difficult tofully grasp the full potential of polymorphism until you get somepractice with it and see exactly what happens under differentscenarios. We’re only going to talk about polymorphism, likethe other topics, at the basic level.
There are 2 basic types of polymorphism. Overridding, alsocalled run-time polymorphism, and overloading, which is referred to ascompile-time polymorphism. This difference is, for methodoverloading, the compiler determines which method will beexecuted, and this decision is made when the code gets compiled.Which method will be used for method overriding is determined atruntime based on the dynamic type of an object.
Let’s look at some code:
' Base class for library assets
Public MustInherit Class LibraryAsset
' Default fine per day for overdue items
Private Const _finePerDay As Double = 1.25
' Due date for an item that has been checked out
Private _dueDate As DateTime
Public Property DueDate() As DateTime
Get
Return _dueDate
End Get
Set(ByVal Value As DateTime)
_dueDate = Value
End Set
End Property
' Calculates the default fine amount for an overdue item
Public Overridable Function CalculateFineTotal() As Double
Dim daysOverdue As Int32 = CalculateDaysOverdue()
If daysOverdue > 0 Then
Return daysOverdue * _finePerDay
Else
Return 0.0
End If
End Function
' Calculates how many days overdue for an item being returned
Protected Function CalculateDaysOverdue() As Int32
Return DateDiff(DateInterval.Day, _dueDate, DateTime.Now())
End Function
End Class
' Magazine class that inherits LibraryAsset
Public NotInheritable Class Magazine
Inherits LibraryAsset
End Class
' Book class that inherits LibraryAsset
Public NotInheritable Class Book
Inherits LibraryAsset
' This is morphing the CalculateFineTotal() function of the base class.
' This function overrides the base class function, and any call
' to CalculateFineTotal from any instantiated Book class will
' use this function, not the base class function.
' This type of polymorphism is called overriding.
Public Overrides Function CalculateFineTotal() As Double
Dim daysOverdue As Int32 = CalculateDaysOverdue()
If daysOverdue > 0 Then
Return daysOverdue * 0.75
Else
Return 0.0
End If
End Function
End Class
' AudioCassette class that inherits LibraryAsset
Public NotInheritable Class AudioCassette
Inherits LibraryAsset
' This is morphing the CalculateFineTotal() function of the base class.
' This is morphing the CalculateFineTotal(double) function of the
' audiocassette class.
' This function overrides the base class function, and any call
' to CalculateFineTotal() from any instantiated AudioCassette
' Class will use this function, not the base class function.
' This type of polymorphism is called overloading and overriding.
Public Overloads Overrides Function CalculateFineTotal() As Double
Dim daysOverdue As Int32 = CalculateDaysOverdue()
If daysOverdue > 0 Then
Return daysOverdue * 0.25
Else
Return 0.0
End If
End Function
' This is morphing the CalculateFineTotal() function of the
' audiocassette class.
' This type of polymorphism is called overloading.
Public Overloads Function CalculateFineTotal(ByVal finePerDay As Double) As Double
Dim daysOverdue As Int32 = CalculateDaysOverdue()
If daysOverdue > 0 AndAlso finePerDay > 0.0 Then
Return daysOverdue * finePerDay
Else
Return 0.0
End If
End Function
End Class
You see our library asset class. Pay attention to theoverridable function CalculateFineTotal(). In LibraryAsset, wehave defined the default functionality for this method that any derivedclasses can use. Any class derived from LibraryAsset can use thisdefault behavior and calculate fines based on the defaultimplementation of $1.25 per day late. This is true for ourMagazine class. We didn’t override the function so when late feesare calculated for late magazine returns, it will use the defaultimplementation.
Now look at the book class. We have overridden theCalculateFineTotal to use a different value when determining latefees. The overrides keywork in VB tells the caller that anymethod call will use the virtual method found in Book, not the defaultimplementation found in LibraryAsset. We have implemented runtimepolymorphism – method overriding.
Lets move on to AudioCassette. Here we have the same methodoverriding we found in the book class. Fines are calculated basedon $0.25 per day. Notice we’ve added something extra. We’veadded the Overloads keywork to our function and to a new function withthe same name, except the new function now accepts a parameter. Now the caller can call either method, and depending on whether or nota parameter is passed, that determines with method will beexecuted. Notice we do not include the overrides keywork in the2nd function with a parameter. This is because not method existsin LibraryAsset with that same signature (accepting a parameter of typedouble). You can only override methods with the same signature ina base class.
Now lets look at some code that creates all these library items andchecks them in and cacluates our fines based on returning them 3 dayslate:
Public Class Demo
Public Sub Go()
' Set the due date to be three days ago
Dim dueDate As DateTime = DateAdd(DateInterval.Day, -3, Now())
ReturnMagazine(dueDate)
ReturnBook(dueDate)
ReturnAudioCassette(dueDate)
End Sub
Public Sub ReturnMagazine(ByVal dueDate As DateTime)
Dim myMagazine As LibraryAsset = New Magazine
myMagazine.DueDate = dueDate
Dim amountDue As Double = myMagazine.CalculateFineTotal()
Console.WriteLine("Magazine: {0}", amountDue.ToString())
End Sub
Public Sub ReturnBook(ByVal dueDate As DateTime)
Dim myBook As LibraryAsset = New Book
myBook.DueDate = dueDate
Dim amountDue As Double = myBook.CalculateFineTotal()
Console.WriteLine("Book: {0}", amountDue.ToString())
End Sub
Public Sub ReturnAudioCassette(ByVal dueDate As DateTime)
Dim myAudioCassette As AudioCassette = New AudioCassette
myAudioCassette.DueDate = dueDate
Dim amountDue As Double
amountDue = myAudioCassette.CalculateFineTotal()
Console.WriteLine("AudioCassette1: {0}", amountDue.ToString())
amountDue = myAudioCassette.CalculateFineTotal(3.0)
Console.WriteLine("AudioCassette2: {0}", amountDue.ToString())
End Sub
End Class
The output will look like the following:
Magazine: 3.75
Book: 2.25
AudioCassette1: 0.75
AudioCassette2: 9
You can see how all of our output was different, based on the methodthat was executed. We created a new Magazine, which is a type ofLibraryAsset. That is why the instantiation says “myMagazine AsLibraryAsset”. However, since we actually want a magazine, wecreate a “New Magazine”. Same thing with book. For Book,its a little bit more tricky. Since we created a Book of the typeLibraryAsset, this is where the polymorphism comes into play. Book overrides the CalculateFineTotal of LibraryAsset. Audiocassette is a little bit different. It actually extends theimplementation of LibraryAsset by including an overloaded function forCalculateFineTotal(). If we weren’t going to use the functionthat took a parameter, we would create it the same way we created theBook and Magazine classes. But in order to use the overloadedfunction, we have to create a new AudioCassette of the typeAudioCassette, because LibraryAsset doesn’t support the overloadedfunction.
Only the Magazine used the default method found in the baseclass. Book and AudioCassette used their own implementations ofthe method. Also, at compile time, the decision was made whichmethod would be used when we calculate amountDue for the AudioCassetteclass. The first call used the 1st method in AudioCassettewithout parameters. The 2nd call used the 2nd method with aparameter.
Currently listening to: Paul Revere - Beastie Boys

Related...
http://codebetter.com/blogs/raymond.lewallen/archive/2005/03/15/59836.aspx | Comments