An abstract class is basically an abstract concept. The main crux in
understanding an abstract class is understanding WHY you want to use them.
I'll try to explain this.
Let's say for example that I want to make a program that handles payroll for
a company.
In this company there are 2 types of employees, salesmen and engineers.
The Salesmen's wages rely on their performances, whereas the engineers wages
are fixed.
This means working out these employees wages is going to be completely
different.
This situation would suggest that Salesmen and Engineers would be 2
different classes e.g:
public class Salesman
{
public decimal WorkOutWages()
{
decimal commission = 0m;
foreach(Sale sale in SalesMade)
{
commission += sale.Commission;
}
return commission;
}
}
public class Engineer
{
public decimal WorkOutWages()
{
return MonthlyWage;
}
}
However if I follow this approach, the code to use these objects becomes
kinda clunky.
For example:
public void WorkOutTotalWageCost()
{
decimal total = 0m;
foreach(Engineer eng in GetEngineers())
{
total+=eng.WorkOutWages();
}
foreach(Salesman sales in GetSalesmen())
{
total+=sales.WorkOutWages();
}
}
Image how ghastly that code would become if you added Managers, Call Centre
staff and so on to the payroll. You'd add the SAME code for each different
type of employee. That'd be horrible.
To get around this problem we would use abstraction and this is where an
abstract class would come in handy.
As all of these Salesmen and Engineers are Employees, we instead create an
Employee class, however we will never explicitly use this Employee class, so
we make it abstract.
public abstract class Employee
{
protected Employee()
{
}
public abstract decimal WorkOutWages();
}
We then change the implementation of the "concrete" classes like this:
public class Salesman:Employee
{
public override decimal WorkOutWages()
{
decimal commission = 0m;
foreach(Sale sale in SalesMade)
{
commission += sale.Commission;
}
return commission;
}
}
public class Engineer:Employee
{
public override decimal WorkOutWages()
{
return MonthlyWage;
}
}
Now when we work out the total cost our job becomes much easier.
public void WorkOutTotalWageCostl()
{
decimal total = 0m;
foreach(Employee emp in GetEmployees())
{
total+=emp.WorkOutWages();
}
}
Now at this point it might be rightly stated: "Why not use interfaces?" E.G
public interface IEmployee
{
decimal WorkOutWages();
}
public class Salesman: IEmployee
{
public decimal WorkOutWages()
{
decimal commission = 0m;
foreach(Sale sale in SalesMade)
{
commission += sale.Commission;
}
return commission;
}
}
public class Engineer: IEmployee
{
public decimal WorkOutWages()
{
return MonthlyWage;
}
}
public void WorkOutTotalWageCostl()
{
decimal total = 0m;
foreach( IEmployee emp in GetEmployees() )
{
total+=emp.WorkOutWages();
}
}
Interfaces would solve this problem equally as well but the main problem
with interfaces is that each implementation of an interface needs to be
built from the ground up and you can't easily share functionality between
objects that implement the same interface.
For example, regardless of what kind of employee you are, being fired from
your job will be roughly the same (e.g).
public void FireEmployee(Company company)
{
company.Office.GetDesk(this).ClearOutDesk();
company.Mail.SendP45(this));
company.Employees.Remove(this);
}
If I used an interface I would have to create that code TWICE in the two
different objects.
public class Salesman: IEmployee
{
public override decimal WorkOutWages()
{
decimal commission = 0m;
foreach(Sale sale in SalesMade)
{
commission += sale.Commission;
}
return commission;
}
public void FireEmployee(Company company)
{
company.Office.GetDesk(this).ClearOutDesk();
company.Mail.SendP45(this));
company.Employees.Remove(this);
}
}
public class Engineer: IEmployee
{
public override decimal WorkOutWages()
{
return MonthlyWage;
}
public void FireEmployee(Company company)
{
company.Office.GetDesk(this).ClearOutDesk();
company.Mail.SendP45(this));
company.Employees.Remove(this);
}
}
This causes either duplicate code or creating a static method for the
objects to share. Both of these solutions aren't as great as they could be.
Using an abstract class though I can just put that code in the Employee
class, like this:
public abstract class Employee
{
protected Employee()
{
}
public abstract decimal WorkOutWages();
public void FireEmployee(Company company)
{
company.Office.GetDesk(this).ClearOutDesk();
company.Mail.SendP45(this));
company.Employees.Remove(this);
}
}
And the problem is solved! :)
So now if we want to close the company (say we've gone bust) we can use the
concrete implementation of firing people to all the employees:
public void CloseDownCompany()
{
foreach(Employee emp in GetEmployees())
{
emp.FireEmployee();
}
}
HTH
Simon
<N.RATNAKARwrote in message news:OS**************@TK2MSFTNGP02.phx.gbl...
hai,
what is abstract class and abstract method