Want to see what people are talking about? See the latest forum posts.
*/

Other Views

corner
*/

C# School - Abstract Classes and Interfaces - Lesson #7 - Page 1

                     Next Page



Abstract classes and Interfaces

If you are new to C# School
This is the 7th in the series of lessons of our C# School. The C# School is a kind of interactive learning platform where those who want to learn .NET with C# can find help and support. With one issue a week, describing some areas of the C# Programming Language with the Microsoft .Net Platform, this is not the same traditional passive tutorial where the author only writes and the reader only reads. There will be exercise problems at the end of each issue, which the reader is expected to solve after reading the issue. The solution to these problems will be provided in the next issue for testing purposes. There is also a dedicated message board attached with the school, where you can ask questions about the article, and the author will respond to your question within 2/3 days. You can send your suggestions, feedback or ideas on how these lessons can be improved to either the Author ( farazrasheed@acm.org)or the WEBMASTER ( info@programmersheaven.com).

For previous lessons: Lesson Plan
Today we will explore abstract classes and interfaces. We will explore the idea behind abstract methods, abstract classes, interfaces and how they are implemented in C#. Later we will see how to cast to and from the interface reference by using the is and as operators.

Abstract Classes
Abstract classes can be simply defined as incomplete classes.
  • Abstract classes contain one or more incomplete methods called abstract methods.
  • The abstract class only provides the signature or declaration of the abstract methods and leaves the implementation of these methods to derived or sub-classes.
  • Abstract methods and abstract classes are marked with the abstract keyword.
  • An abstract class itself must be marked with the abstract keyword.
  • Since abstract classes are incomplete, they can not be instantiated. They must be sub-classed in order to use their functionality. This is the reason why an abstract class can't be sealed.
  • A class inheriting an abstract class must implement all the abstract methods in the abstract class, or it too must be declared as an abstract class.
  • A class inheriting an abstract class and implementing all its abstract methods is called the concrete class of the abstract class.
  • We can declare a reference of the type of abstract class and it can point to the objects of the classes that have inherited the abstract class.
Let us declare an abstract class with two concrete properties and an incomplete (abstract) method.

	abstract class TaxCalculator
	{
		protected double itemPrice;
		protected double tax;
		
		public abstract double CalculateTax();
        
		public double Tax
		{
			get { return tax; }
		}
		public double ItemPrice
		{
			get { return itemPrice; }
		}
	}


The TaxCalculator class contains two fields: itemPrice and applied tax. It contains an abstract method CalculateTax() which calculates the tax applied on the itemPrice and stores it in the field tax. The CalculateTax() method is made abstract so the concrete sub-classes can provide their own criteria for applying the tax on the itemPrice. The class also contains two public read only properties used to access the two private fields. If we try to instantiate this abstract class in the Main() method

static void Main()
	{
		TaxCalculator taxCalc = new TaxCalculator();
	}


The compiler will complain like:

Cannot create an instance of the abstract class or interface 'CSharpSchool.TaxCalculator'

In order to create an instance of the TaxCalculator class, we need to sub-class it. Let us now inherit a class from the abstract TaxCalculator class calling it SalesTaxCalculator.

	class SalesTaxCalculator : TaxCalculator
	{
		public SalesTaxCalculator(double itemPrice)
		{
			this.itemPrice = itemPrice;
		}
		public override double CalculateTax()
		{
			tax = 0.3 * itemPrice;
			return itemPrice + tax;
		}
	}


The SalesTaxCalculator class inherits the TaxCalculator and overrides its CalculateTax() method. It applies 30% tax on the price of an item (a bit harsh!) and returns the new price of the item. The SalesTaxCalculator class also defines a constructor that takes itemPrice as its parameter. If we don't provide the implementation of the CalculateTax() method in SalesTaxCalculator

	class SalesTaxCalculator : TaxCalculator
	{
		public SalesTaxCalculator(double itemPrice)
		{
			this.itemPrice = itemPrice;
		}
	/*	public override double CalculateTax()
		{
			tax = 0.3 * itemPrice;
			return itemPrice + tax;
		}*/
	}


We will get a compile time error:

'CSharpSchool.SalesTaxCalculator' does not implement inherited abstract member 'CSharpSchool.TaxCalculator.CalculateTax()'

Now, un-comment the overridden CalculateTax() method in SalesTaxCalculator. Since we have overridden the CaculateTax() method of TaxCalculator in the SalesTaxCalculator class, we can create its instance in the Main() method.

class Test
{
	static void Main()
	{
		SalesTaxCalculator salesTaxCalc = new SalesTaxCalculator(225);
		double newPrice = salesTaxCalc.CalculateTax();
                Console.WriteLine("The item price has changed 
                  because of sales tax from {0} $ to {1} $", 
                  salesTaxCalc.ItemPrice, newPrice);
		Console.WriteLine("Tax applied = {0} $", salesTaxCalc.Tax);
	}
}


Here, we have instantiated the SalesTaxCalculator class just like a regular class and accessed its members. The output of the above program will be:

The item price has changed because of sales tax from 225 $ to 292.5 $
Tax applied = 67.5 $
Press any key to continue


We can also use an abstract class type (TaxCalculator) reference to handle an object of its concrete class (SalesTaxCalculator) in our Main() method.

static void Main()
{
	TaxCalculator taxCalc = new SalesTaxCalculator(225);
	double newPrice = taxCalc.CalculateTax();
        Console.WriteLine("The item price has changed because of 
           sales tax from {0} $ to {1} $", taxCalc.ItemPrice, newPrice);
	Console.WriteLine("Tax applied = {0} $", taxCalc.Tax);
}


We can derive as many concrete classes as we want from the abstract TaxCalculator class, as long as they provide the definition of its abstract methods. Here is another concrete class (WarSurchargeCalculator) of the abstract TaxCalculator class.

class WarSurchargeCalculator : TaxCalculator
{
	public WarSurchargeCalculator(double itemPrice)
	{
		this.itemPrice = itemPrice;
	}
	public override double CalculateTax()
	{
		tax = 0.5 * itemPrice;
		return itemPrice + tax;
	}
}


The WarSurchargeCalculator can be used similarly in the Main() method.


                     Next Page



corner
© 1996-2008 CommunityHeaven LLC. All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
North American business development: Nicolai Wadstrom. Publisher: Lars Hagelin.
Resource Listings