Friday, September 24, 2010

Inheritance and Polymorphism - OOPS

Inheritance and Polymorphism

In this article, we will discuss two important concepts of object-oriented programming — inheritance and polymorphism. Inheritance permits you to use the existing features of a class as it is and add a few of your own. Instead of using all the features of an existing class on an as-is-where-is basis, we can also override a few of them and provide our own implementation of them.

For example, a class that can create a window may already exist, which we can extend to create a button, a list box or a combo box. While extending a class, the existing class remains unchanged. The new class is called ‘derived class’, whereas, the existing class is called ‘base class’. The main advantage of inheritance is code reusability. The code reusability is of great help in the case of distributing class libraries. A programmer can use a class created by another person or company, and, without modifying it, derive other classes from it. C# goes one step further and allows cross language inheritance too.

Polymorphism and inheritance go hand in hand. Polymorphism implies the existence of an entity in different forms. Polymorphism allows classes to provide different implementations of a method that can be called in the same way. Polymorphism can be of three types—inheritance polymorphism, interface polymorphism and polymorphism through abstract classes.

Let us first write a program that shows inheritance at work. Suppose a bank has a very generic class called account that allows debit and credit transactions on an account. A bank has to maintain various accounts like savings bank account, fixed deposit account, current account, etc. Every account has a few unique features. For example, a savings account can be operated only ten times in a month. Similarly, it needs to have a minimum balance against it. On the other hand, a current account allows unlimited transactions to be performed. So we can create more specific classes to maintain different kinds of accounts from the same account class. These classes can use the basic functionality of the account class and add their own account-specific functionality. Following code shows the base class account and derived classes savingaccount and currentaccount.

class account
{
protected string name ;
protected float balance ;
public account ( string n, float b )
{
name = n ;
balance = b ;
}
public void deposit ( float amt )
{
balance += amt ;
}
public void withdraw ( float amt )
{
balance -= amt ;
}
public void display( )
{
Console.WriteLine ( “Name: {0} Balance: {1}”, name, balance ) ;
}
}
class savingaccount : account
{
static int accno = 1000 ;
int trans ;
public savingaccount ( string s, float b ) : base ( s, b )
{
trans = 0 ;
accno++ ;
}
public void withdraw ( float amt )
{
if ( trans >= 10 )
{
Console.WriteLine (“Number of transactions exceed 10” ) ;
return ;
}
if ( balance - amt < 500 )
Console.WriteLine ( “Below minimum balance” ) ;
else
{
base.withdraw ( amt ) ;
trans++ ;
}
}
public void deposit ( float amt )
{
if ( trans >= 10 )
{
Console.WriteLine ( “Number of transactions exceed 10” ) ;
return;
}
base.deposit ( amt ) ;
trans++ ;
}
public void display( )
{
Console.WriteLine ( “Name: {0} Account no.: {1} Balance: {2} ”,
name, accno, balance ) ;
}
}
class currentaccount : account
{
static int accno = 1000 ;
public currentaccount ( string s, float b ) : base ( s, b )
{
accno++ ;
}
public void withdraw ( float amt )
{
if ( balance - amt < 0 )
Console.WriteLine ( “No balance in account” ) ;
else
balance -= amt ;
}
public void display( )
{
Console.WriteLine ( “Name: {0} Account no.: {1} Balance: {2} ”,
name, accno, balance ) ;
}
}
The savingaccount class has two data members—accno that stores account number, and trans that keeps track of the number of transactions. We can create an object of savingaccount class as shown below.

savingaccount s = new savingaccount ( “Amar”, 5600.00f ) ;
From the constructor of savingaccount class we have called the two-argument constructor of the account class using the base keyword and passed the name and balance to this constructor using which the data member’s name and balance are initialised.

We can write our own definition of a method that already exists in a base class. This is called method overriding. We have overridden the deposit( ) and withdraw( ) methods in the savingaccount class so that we can make sure that each account maintains a minimum balance of Rs. 500 and the total number of transactions do not exceed 10. From these methods we have called the base class’s methods to update the balance using the base keyword. We have also overridden the display( ) method to display additional information, i.e. account number.

Working of currentaccount class is more or less similar to that of savingaccount class.

Using the derived class's object, if we call a method that is not overridden in the derived class, the base class method gets executed. Using derived class's object we can call base class's methods, but the reverse is not allowed.

Unlike C++, C# does not support multiple inheritance. So, in C# every class has exactly one base class.

Now, suppose we declare reference to the base class and store in it the address of instance of derived class as shown below.

account a1 = new savingaccount ( “Amar”, 5600.00f ) ;
account a2 = new currentaccount ( “MyCompany Pvt. Ltd.”, 126000.00f) ;
Such a situation arises when we have to decide at run-time a method of which class in a class hierarchy should get called. Using a1 and a2, suppose we call the method display( ), ideally the method of derived class should get called. But it is the method of base class that gets called. This is because the compiler considers the type of reference (account in this case) and resolves the method call. So, to call the proper method we must make a small change in our program. We must use the virtual keyword while defining the methods in base class as shown below.

public virtual void display( )
{
}
We must declare the methods as virtual if they are going to be overridden in derived class. To override a virtual method in derived classes we must use the override keyword as given below.

public override void display( )
{
}
Now it is ensured that when we call the methods using upcasted reference, it is the derived class's method that would get called. Actually, when we declare a virtual method, while calling it, the compiler considers the contents of the reference rather than its type.

If we don't want to override base class's virtual method, we can declare it with new modifier in derived class. The new modifier indicates that the method is new to this class and is not an override of a base class method.

Abstract classes and methods
If you analyse the above program carefully, you will notice that the account class is so general that we would
seldom require calling its methods directly. Rather, we would always override them in derived class and call the
derived class's methods. So, instead of defining the functionality in account class we can design the account class in such a way that it would only specify what functionality the derived classes should have. So, an abstract class always serves as the base class for other classes. We can achieve this by declaring the class as abstract.

abstract class account
{
abstract public void deposit( ) ;
abstract public void withdraw( ) ;
abstract public void display( ) ;
}
An abstract method does not have a definition in base class. As such, it is similar to a pure virtual function of C++. We cannot instantiate objects of abstract classes. A class that inherits an abstract class has to define all the abstract methods declared in the class.

Interfaces
Polymorphism is also achieved through interfaces. Like abstract classes, interfaces also describe the methods that a class needs to implement. The difference between abstract classes and interfaces is that abstract classes always act as a base class of the related classes in the class hierarchy. For example, consider a hierarchy-car and truck classes derived from four-wheeler class; the classes two-wheeler and four-wheeler derived from an abstract class vehicle. So, the class 'vehicle' is the base class in the class hierarchy. On the other hand dissimilar classes can implement one interface. For example, there is an interface that compares two objects. This interface can be implemented by the classes like box, person and string, which are unrelated to each other.

C# allows multiple interface inheritance. It means that a class can implement more than one interface.

The methods declared in an interface are implicitly abstract. If a class implements an interface, it becomes mandatory for the class to override all the methods declared in the interface, otherwise the derived class would become abstract.

One last thing. Be careful while designing an interface. Because, once an interface is published, we cannot change it. We cannot even add a method because all the classes that implement this interface will have to implement this method.

Source : http://www.expresscomputeronline.com/20021118/techspace2.shtml

No comments:

Post a Comment