Abstract Classes with examples
What is an Abstract Class? How and Where to use an abstract class?
These are some common questions but a bit tricky to answer. Bellow I am providing my views and understanding of abstract classes.
Abstract classes are classes that embody coherent and cohesive, but incomplete, concepts, and in turn, make these characteristics available to their specializations via inheritance. People sometimes use the terms "partial type" and "abstract superclass" as synonyms for abstract class. While we would never create instances of abstract classes, we most certainly would make their individual characteristics available to more specialized classes via inheritance.
source - http://www.toa.com/pub/oobasics/oobasics.htm#ac
According to this definition abstract classes can have methods/properties with body and methods/properties with declarations only. In .net all method/property declarations of an abstract class have to be public, but concrete method/property have no such restriction. Also abstract classes can not be initialized. Any concrete class can inherit an abstract class, but all method/property declaration of abstract class have to be implemented by concrete class. If concrete class does not implement all methods/properties .net compiler will give error.
Syntax to use Abstract Classes (VB.Net)
Syntax to use Abstract Classes (C#)
Use Abstract(C#)/MustInherit(VB.Net) keyword to declare an abstract class. Any abstract method, procedure(VB.Net), property or function should have abstract/MustInherit keyword in its declaration. No abstract member can be private in an abstract class.
When a concrete class inherits this abstract class it will have to override each and every abstract member of that class. Use override(C#)/Overrides(Vb.Net) keyword to implement abstract member of an abstract class in a concrete class.
Now comes the big question, where should one use an abstract?
Tactically an abstract class should be used at places where more than one class share certain number of same set of functions but also have some some different functions. For Example,
if Class A, Class B and Class C have two functions which have same functionality, then it is better to create abstract Class MasterABC and inherit this class in other concrete class. But be careful with this as we can only inherit from one class. So your decision of creating an abstract class should be based on through analysis of design.
A more practical example of abstract classes can be seen in Data Access Layer classes. Suppose we are creating data access layer for a database, and there is going to be one class for each Stored Procedure and these stored procedures perform normal CRUD functions on the database.
So I am going to write common functionalities of these classes in one abstract class DataEntity and then inherit my concrete classes (for each SP) with this class.
Before this I would like to mention base logic of my data access layer. Each class will use a datatable to store data either to provide it as argument to any SP or store result-set of any Stored Procedure. DataEntity class will hold all the functions to create, access and loop through the datatable.
Most of the functionality to create and access datatable is present in this class. Now lets create a concrete class which inherits this abstract class. Concrete class will be used to call a stored procedure which returns a result set.
This concrete class provides implementation to all abstract properties and methods of DataEntity class. Similarly classes can be created for any number of stored procedures without repeating the datatable code.
These are some common questions but a bit tricky to answer. Bellow I am providing my views and understanding of abstract classes.
Abstract classes are classes that embody coherent and cohesive, but incomplete, concepts, and in turn, make these characteristics available to their specializations via inheritance. People sometimes use the terms "partial type" and "abstract superclass" as synonyms for abstract class. While we would never create instances of abstract classes, we most certainly would make their individual characteristics available to more specialized classes via inheritance.
source - http://www.toa.com/pub/oobasics/oobasics.htm#ac
According to this definition abstract classes can have methods/properties with body and methods/properties with declarations only. In .net all method/property declarations of an abstract class have to be public, but concrete method/property have no such restriction. Also abstract classes can not be initialized. Any concrete class can inherit an abstract class, but all method/property declaration of abstract class have to be implemented by concrete class. If concrete class does not implement all methods/properties .net compiler will give error.
Syntax to use Abstract Classes (VB.Net)
Public MustInherit Class Sample
' Default Constructor
Public Sub New()
'Some Code
End Sub
Public MustOverride Sub DoWorkSub1()
Public MustOverride Function DoWorkFunction1() as System.Int32
Public MustOverride ReadOnly Property Prop1() as String
Private Sub DoWorkSub2()
'Write code
End Sub
End Class
Public Class ConcreteSample1 : Inherits Sample
Public sub New()
MyBase.New()
'Further Code
End Sub
Public Overrides Sub DoWorkSub1()
End Sub
Public Overrides Function DoWorkFunction1() as System.Int32
return 12
End Function
Public Overrides Property Prop1() as String
Get
return ""
End Get
End Property
End Class
Syntax to use Abstract Classes (C#)
public abstract class Sample
{
// Default Constructor
public Sample() { //Some Code }
public abstract void DoWorkSub1();
public abstract int DoWorkFunction1();
public abstract string Prop1 { get; }
private void DoWorkSub2() { //Write code }
}
public class ConcreteSample1 : Sample
{
public ConcreteSample1() : base() { //Further Code }
public override void DoWorkSub1() { }
public override int DoWorkFunction1() { return 12; }
public override string Prop1 { get { return ""; } }
}
Use Abstract(C#)/MustInherit(VB.Net) keyword to declare an abstract class. Any abstract method, procedure(VB.Net), property or function should have abstract/MustInherit keyword in its declaration. No abstract member can be private in an abstract class.
When a concrete class inherits this abstract class it will have to override each and every abstract member of that class. Use override(C#)/Overrides(Vb.Net) keyword to implement abstract member of an abstract class in a concrete class.
Now comes the big question, where should one use an abstract?
Tactically an abstract class should be used at places where more than one class share certain number of same set of functions but also have some some different functions. For Example,
if Class A, Class B and Class C have two functions which have same functionality, then it is better to create abstract Class MasterABC and inherit this class in other concrete class. But be careful with this as we can only inherit from one class. So your decision of creating an abstract class should be based on through analysis of design.
A more practical example of abstract classes can be seen in Data Access Layer classes. Suppose we are creating data access layer for a database, and there is going to be one class for each Stored Procedure and these stored procedures perform normal CRUD functions on the database.
So I am going to write common functionalities of these classes in one abstract class DataEntity and then inherit my concrete classes (for each SP) with this class.
Before this I would like to mention base logic of my data access layer. Each class will use a datatable to store data either to provide it as argument to any SP or store result-set of any Stored Procedure. DataEntity class will hold all the functions to create, access and loop through the datatable.
'Namespaces
Public MustInherit Class DataEntity
Private m_connectionString As String
Protected m_dataRow As DataRow = Nothing
Protected m_dataTable As DataTable = Nothing
Protected m_enumerator As IEnumerator = Nothing
Private m_mappingName As String = ""
Protected m_EOF As Boolean = True
Public Sub New()
End Sub
Public Sub New(ByVal connectionString As String)
End Sub
''' This is used by GetDateTimeAsString, for more informaton see "about DateTimeFormatInfo class" in the Visual Studio Help. The default is "MM/dd/yyyy".
'''
Public StringFormat As String = "MM/dd/yyyy"
''' AddNew is how you add a new record to your Entity, when saved this row will be an INSERT. All Identity columns and calculated columns are present and available after calling Save().
'''
Public MustOverride Sub AddNew()
''' This is the connection string used in relation for this object.
Public Property ConnectionString() As String
End Property
''' True if MoveNext() moves past the last row or there are 0 rows.
Public ReadOnly Property EOF() As Boolean
End Property
''' After loading your BusinessEntity you can filter (temporary hide) rows. To disable the filter set this property to String.empty. After filter using Iteration via MoveNext will properly respect any filter you have in place.
'''
Public Property Filter() As String
End Property
''' After loading your BusinessEntity you can sort the rows. To disable the sort set this property to String.empty. After settign Sort iteration via MoveNext will properly respect the sort order.
'''
Public Property Sort() As String
End Property
''' After loading your BusinessEntity you can add custom columns, this is typically done to create a calculated column, however, it can be used to add a column just to hold state, it will not be saved to the database of course.
'''
Public Function AddColumn(ByVal name As String, ByVal dataType As System.Type) As DataColumn
End Function
''' You can use this to determine the rowstate of a given row in your BusinessEntity, examples are Added, Deleted, Modified.
'''
Public Function RowState() As DataRowState
End Function
''' The number of rows in your BusinessEntity or Zero if none.
Public ReadOnly Property RowCount() As Integer
End Property
''' Resets the interation process back to the first row.
Public Sub Rewind()
End Sub
''' Advances the enumerator to the next element of the collection.
Public Function MoveNext() As Boolean
End Function
''' This method flushes the Data in the DataTable and nulls out the Current Row, including any DynamicQuery Data. You can call FlushData() and then reload an object.
'''
Public Overridable Sub FlushData()
End Sub
''' Gets a customized view of the table that may include a filtered view, or a cursor position.
Public ReadOnly Property DefaultView() As DataView
End Property
''' This is the ADO.NET DataTable, it holds the data for your BusinessEntity. It is protected so your derived class can have access to it but the consumers of your BusinessEntity cannot. Exposing this publically is not a good idea as your data would be able to be modified without going through you business logic.
'''
Protected Friend Property DataTable() As DataTable
End Property
'''
''' This is the ADO.NET DataRow, it holds the data for your BusinessEntity. It is protected so your derived class can have access to it but the consumers of your BusinessEntity cannot. Exposing this publically is not a good idea as your data would be able to be modified without going through you business logic.
'''
Protected Friend Property DataRow() As DataRow
End Property
End Class
Most of the functionality to create and access datatable is present in this class. Now lets create a concrete class which inherits this abstract class. Concrete class will be used to call a stored procedure which returns a result set.
Public Class GetProduct : Inherits DataEntity
Private m_searchParams As Parameters
Public Sub New()
MyBase.New()
End Sub
Public Sub New(connectionString)
MyBase.New(connectionString)
End Sub
Friend Overrides Sub CreateTable()
m_dataTable = New DataTable
With m_dataTable
.TableName = "GetProduct"
End With
End Sub
Public Overrides Sub AddNew()
End Sub
Public Property SearchParameters() As Parameters
Get
If (m_searchParams Is Nothing) Then m_searchParams = New Parameters
Return m_searchParams
End Get
Set(ByVal value As Parameters)
m_searchParams = Value
End Set
End Property
'''
''' Executes the stored procedure.
'''
'''
Public Overrides Sub Execute()
Dim _cmd As SqlCommand = New SqlCommand
Dim _connection As SqlConnection = New SqlConnection(MyBase.ConnectionString)
With _cmd
.Connection = _connection
.CommandType = CommandType.StoredProcedure
.CommandText = "pGetProduct"
If Me.SearchParameters.ProductID = 0 Then
.Parameters.Add(New SqlParameter("@" + SearchColumnNames.ProductID, SqlDbType.Int))
Else
.Parameters.Add(New SqlParameter("@" + SearchColumnNames.ProductID, Me.SearchParameters.ProductID))
End If
End With
_cmd.Connection.Open()
m_dataTable = New DataTable
m_dataTable.Load(_cmd.ExecuteReader, LoadOption.OverwriteChanges)
_cmd.Connection.Close()
_cmd = Nothing
End Sub
Public Class Parameters
Private m_ProductID As Integer
'''The ProductID property.
'''
'''
Public Property ProductID() As Integer
End Property
End Class
End Class
This concrete class provides implementation to all abstract properties and methods of DataEntity class. Similarly classes can be created for any number of stored procedures without repeating the datatable code.
Labels: .net, Abstract Classses, C#, OOPS, VB.Net


0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home