what is abstract class and abstract method

  • Thread starter Thread starter N.RATNAKAR
  • Start date Start date
Abstract Class: A class that you can not instantiate. Only inherit from.
Abstract Method: Included in an abstract class. Allow for custom definition
of method body, provided the signature.
 
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.RATNAKAR said:
hai,
what is abstract class and abstract method

An real-world example may be the best illustration.

In my company, we have two kinds of purchasing documents that are
almost identical: a PO and an RMA. A PO, or Purchase Order, is an order
to buy something from a supplier. an RMA, or Returned Materials
Authorization, is an order to send product back to a supplier (for
example if it arrives damaged).

These two documents are almost identical.

If I were modeling them in an object oriented language, I might want to
use inheritance so that the two classes, PurchaseOrder and RMA, could
share code and properties, since they're almost identical. However,
from a modeling point of view I have a problem: the two documents are
not hierarchically related. That is to say: a PO is not a type of RMA,
and an RMA is not a type of PO. So, I would create a third class:

public class PurchasingDocument
{
...
}

public class PurchaseOrder : PurchasingDocument { ... }

public class RMA : PurchasingDocument { ... }

Most of the code would be in the PurchasingDocument class so that it
would be inherited by PurchaseOrder and RMA. Those two classes would
have code only where they were different.

So far, so good.

However, there is a problem. Now I have a third class,
PurchasingDocument, that anyone can instantiate. Anyone can say "new
PurchasingDocument(...)". Unfortunately, that doesn't make any sense.
My business doesn't have a thing called a "purchasing document". That
class is there _only_ to serve as a base for PurchaseOrder and RMA,
which are real things. It's not meant to be created in its own right.

So... how do I indicate that PurchasingDocument is just an artefact of
my class hierarchy and not a real business entity that I want to be
able to create separately?

I use "abstract".

public abstract class PurchasingDocument
{
...
}

public class PurchaseOrder : PurchasingDocument { ... }

public class RMA : PurchasingDocument { ... }

Now I have the same thing I had before, except that I've diasllowed
anyone from creating a PurchasingDocument. They can create
PurchaseOrder or RMA, but not PurchasingDocument. That's what abstract
classes are for.

Now, there may be some methods or properties that have no common
functionality between my two classes PurchaseOrder and RMA, but which
need to _exist_ in both classes. For example, the physical, printed
"look" of a PurchaseOrder and an RMA are different, so writing a
Print() method in PurchasingDocument doesn't make much sense. I'd like
to be able to say that a PurchasingDocument (of either kind) has to
_have_ a Print() method, but I want to defer defining exactly what that
does to the child classes. I can do that like this:

public abstract class PurchasingDocument
{
public abstract void Print();
}

public class PurchaseOrder : PurchasingDocument
{
public override void Print() { ... }
}

public class RMA : PurchasingDocument
{
public override void Print() { ... }
}

What this says is that every (non-abstract) class that _inherits_ from
PurchasingDocument MUST define a Print() method, and it must take no
arguments and return void. However, each child class is free to
implement that method in its own way. The idea is that we know that any
PurchasingDocument can be printed, but until we get a specific
document, we don't know _how_ to print it.

This does _not_ mean (as many newbies imagine) that an abstract class
can't have normal properties and methods with implementations. Of
course it can. Those methods and properties are defined as the same for
all child classes. What an abstract class can _also_ do, though, is
declare methods and properties that will be supplied by all child
classes, but defer the actual code to the child class, in effect
saying, "Every one of my children must have this method, but I'm not
supplying any common implementation."
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top