Website Design United States, Website Design California, Website Designing United States, Website Designing California

Abstract Class Example

You may have noticed that the bank account example we did had some similar code in both the SavingsAccount and CheckingAccount. Since we used interfaces we could not have that code in the BankAccount interface because interfaces do not allow that. Now we can do it with an abstract class and have the common code in that class. So we can inherit the abstract class and add what we need to make it a specific account. This example we will do just that.

Open Visual Studio .NET and create a new Console Application called BankAccount2. Since this example is going to be quite different we will start from scratch. To begin add a new class called BankAccount. Again to make abstract you use the keyword "MustInherit".

Public MustInherit Class BankAccount

End Class

We will keep the same properties and methods as the interface had only now we can also put code in them. The BankAccount interface had properties, AccountNumber and Balance, and methods, Debit and Credit. Now comes the decisions of what the abstract class will do. Generally it has code that will be the same in all child classes (classes that inherit it) and forces what isn't common to all be overridden. You could supply suggested code and allow child classes to override it if you wish.

Lets examine SavingsAccount and BankAccount from the previous example to see what is common to both so we can put it in the abstract BankAccount class. AccountNumber, Balance, and Credit are all identical and would likely be the same in any child class. So lets put it in the BankAccount class.

Private mdblBalance As Double
Private mintNumber As Integer

Public Property AccountNumber() As Integer
Get
Return mintNumber
End Get
Set(ByVal Value As Integer)
If mintNumber = 0 And Value > 0 Then
mintNumber = Value
End If
End Set
End Property

Public ReadOnly Property Balance() As Double
Get
Return mdblBalance
End Get
End Property

Public Sub Credit(ByVal Amount As Double)
If Amount > 0 Then
mdblBalance += Amount
End If
End Sub

None of the above need the "Implements" any more since we are not implementing an interface.

As before the Debit function is a little different in SavingsAccount and CheckingAccount. This brings us to a bit of a snag. Since mdblBalance is private we do not have access to it and therefore cannot directly change it. Since the Balance property is ReadOnly we cannot use it to change mdblBalance either. So what do we do? Well there are two options that come to mind. One is to supply a default Debit function which would look exactly like the CheckingAccount, overriding it in SavingsAccount to check to see if they have enough money and if they do call the Debit function in BankAccount. The other is to make mdblBalance "Protected" in scope. Protected means anything inside the same class or any derived (child) class can access it directly.

In order to keep mdblBalance Private we need to declare an overridable Debit function that has the same code as the Debit function in CheckingAccount. If you want to go the Protected way then a simple MustOverride Debit function will do.

Public Overridable Function Debit(ByVal Amount As Double) As Boolean
If Amount > mdblBalance Then
Return False
Else
mdblBalance -= Amount
Return True
End If
End Function

' Or

Protected mdblBalance As Double

MustOverride Function Debit(ByVal Amount As Double) As Boolean

Now lets create the new SavingsAccount and CheckingAccount by adding two classes with those names

Public Class SavingsAccount
Inherits BankAccount

End Class

Public Class CheckingAccount
Inherits BankAccount

End Class

Lets start with the CheckingAccount class. If you have the overridable Debit function then you are done! Seriously there is no code needed because it is already in the BankAccount class. If you went the Protected way then you must declare the Override Debit function directly manipulating mdblBalance.

Public Overrides Function Debit(ByVal Amount As Double) As Boolean
If Amount > 0 Then
mdblBalance -= Amount
Return True
Else
Return False
End If
End Function

Now for the SavingsAccount either way you will have to have override Debit function. If Debit is overridable then we will override it checking to see if they have enough money before we debit. If they do we will call the Debit function the BankAccount (the base class). If Debit is "MustOverride" (the Protected way) then it will look similar to the CheckingAccount only first making sure there is enough money.

Public Overrides Function Debit(ByVal Amount As Double) As Boolean
If Amount > 0 Then
If MyBase.Balance < Amount Then
Return False ' not enough money in account
Else
MyBase.Debit (Amount)
Return True
End If
Else
Return False ' amount isn't positive
End If
End Function

' Protected way

Public Overrides Function Debit(ByVal Amount As Double) As Boolean
If Amount > 0 Then
If mdblBalance < Amount Then
Return False ' not enough money in account
Else
mdblBalance -= Amount
Return True
End If
Else
Return False ' amount isn't positive
End If
End Function

One final thing is the constructors (Public Sub New()). Unlike the interface these can be defined in the abstract class and can have code in them. SavingsAccount and CheckingAccount both have two constructors and one of them had no parameters which set mdblBalance to zero. Since they are both the same it can be moved into the BankAccount abstract class. The constructor that took in the starting balance is going to be different in SavingsAccount and CheckingAccount depending on whether you made mdblBalance protected or not.

' BankAccount constructor with no parameters
Public Sub New()
mdblBalance = 0
End Sub

' Private mdblBalance As Double
' SavingsAccount
Public Sub New(ByVal StartAmount As Double)
MyBase.>New()
If StartAmount > 0 Then
MyBase.Credit (StartAmount)
End If
End Sub

' CheckingAccount
Public Sub New(ByVal StartAmount As Double)
MyBase.New()
MyBase.Credit (StartAmount)
End Sub

' Protected mdblBalance As Double
' SavingsAccount
Public Sub New(ByVal StartAmount As Double)
mdblBalance = 0
If StartAmount > 0 Then
mdblBalance = StartAmount
End If
End Sub

' CheckingAccount
Public Sub New(ByVal StartAmount As Double)
mdblBalance = StartAmount
End Sub

Now time to test. If you copy the code from the module in the Class & Interface Example Executable and run the program it should work exactly the same.

So Abstract class or Interface? It all depends on the situation. The only main difference is an Abstract class can have code. If you want a variable to have at least a certain properties and methods and don't want to supply any code then make an interface. If you see code that is common to all derived classes then make it abstract.

WEB DESIGN INDIA
42 B Malviya Nagar , New Delhi-110017

Skype: manmeetsi
Email: support.webdesignindia@gmail.com
Tel: 91-011-40502005, 9810067295

 















 


© 2008-2009 dotnet4all.com