Through inheritance, a class can be used as more than one type; it can be used as its own type, any base types, or any interface type if it implements interfaces. This is called polymorphism.
When a derived class inherits from a base class, it gains all the methods, fields, properties and events of the base class. To change the data and behavior of a base class, you have two choices: you can replace the base member with a new derived member, or you can override a virtual base member.
Replacing a member of a base class with a new derived member requires the new keyword. If a base class defines a method, field, or property, the new keyword is used to create a new definition of that method, field, or property on a derived class. The new keyword is placed before the return type of a class member that is being replaced. For example:
-----------------------------Example 1---------------------------------------------------------
#region [TestingPolyNew]
///
/// Testing Polymorphism with new keyword
/// Replacing a member of a base class with a new derived member requires the new keyword.
/// If a base class defines a method, field, or property, the new keyword is used to create a new definition of that method, field, or property on a derived class.
///
///
public class CBaseClass
{
public void DoWork() { }
public int WorkField;
public int WorkProperty
{
get { return 0; }
}
}
public class CDerivedClass : CBaseClass
{
public new void DoWork() { }
public new int WorkField;
public new int WorkProperty
{
get { return 0; }
}
}
public class CTestPoly
{
public void Test()
{
//When the new keyword is used, the new class members are called instead of the base class members
//that have been replaced. Those base class members are called hidden members. Hidden class members
//can still be called if an instance of the derived class is cast to an instance of the base class.
//For example:
CDerivedClass B = new CDerivedClass();
B.DoWork(); // Calls the new method.
CBaseClass A = (CBaseClass)B;
A.DoWork(); // Calls the old method.
}
static void Main()
{
CTestPoly objTestPoly = new CTestPoly();
objTestPoly.Test();
}
}
#endregion [TestingPolyNew]
-----------------------------Example 2--------------------------------------------------------
In order for an instance of a derived class to completely take over a class member from a base class, the base class has to declare that member as virtual.
A derived class then has the option of using the override keyword, instead of new, to replace the base class implementation with its own. For example:
#region [TestingVirtualPoly]
///
/// Testing polymorphism with virtual/override
///
/// In order for an instance of a derived class to completely take over a class member from a base class,
/// the base class has to declare that member as virtual. A derived class then has the option of using the
/// override keyword, instead of new, to replace the base class implementation with its own.
public class CA
{
public virtual void DoWork() { }
public virtual int WorkProperty
{
get { return 0; }
}
}
public class CB : CA
{
public override void DoWork() { }
public override int WorkProperty
{
get { return 0; }
}
}
public class CTestVirutalPoly
{
public void Test()
{
CB B = new CB();
B.DoWork(); // Calls the new method.
CA A = (CA)B;
A.DoWork(); // Also calls the new method.
}
static void Main()
{
CTestVirutalPoly objVP = new CTestVirutalPoly();
objVP.Test();
}
}
#endregion [TestingVirtualPoly]
-----------------------------Example 3--------------------------------------------------------
C# enables methods in derived classes to have the same name as methods in base classes—as long as you are very specific about how the new method should be treated. The following example demonstrates the use of the new and override keywords.
First we declare three classes: a base class called Car, and two classes that derive from it, ConvertibleCar and Minivan. The base class contains a single method, DescribeCar, which sends a description of the car to the console. The derived class methods also include a method called DescribeCar, which displays their unique properties. These methods also call the base class DescribeCar method to demonstrate how they have inherited the properties of the Car class.
In order to highlight the difference, the ConvertibleCar class is defined with the new keyword, while the Minivan class is defined with override.
#region [WhenToUseNewOverride]
///
/// In order to highlight the difference, the ConvertibleCar class is defined with the new keyword,
/// while the Minivan class is defined with override.
///
public class Car
{
public virtual void DescribeCar()
{
System.Console.WriteLine("Four wheels and an engine.");
}
}
public class ConvertibleCar : Car
{
public new virtual void DescribeCar()
{
base.DescribeCar();
System.Console.WriteLine("A roof that opens up.");
}
}
public class MiniVan : Car
{
public override void DescribeCar()
{
base.DescribeCar();
System.Console.WriteLine("Carries seven people.");
}
}
public class CDescribeCars
{
public void Describe()
{
Car car1 = new Car();
car1.DescribeCar();
System.Console.WriteLine("----------------------");
ConvertibleCar car2 = new ConvertibleCar();
car2.DescribeCar();
System.Console.WriteLine("----------------------");
MiniVan car3 = new MiniVan();
car3.DescribeCar();
System.Console.WriteLine("----------------------");
}
public void Test2()
{
Car[] cars = new Car[3];
cars[0] = new Car();
cars[1] = new ConvertibleCar();
cars[2] = new MiniVan();
foreach (Car vehicle in cars)
{
System.Console.WriteLine("Car object: " + vehicle.GetType());
vehicle.DescribeCar();
System.Console.WriteLine("----------");
}
}
static void Main()
{
CDescribeCars objCars = new CDescribeCars();
objCars.Describe();
//output
//Four wheels and an engine.
//----------
//Four wheels and an engine.
//A roof that opens up.
//----------
//Four wheels and an engine.
//Carries seven people.
//----------
objCars.Test2();
//output
//Notice how the ConvertibleCar description is not what you might expect.
//As the new keyword was used to define this method, the derived class method is not
//called—the base class method is called instead. The Minivan object correctly calls
//the overridden method, producing the results we expected.
//Car object: YourApplication.Car
//Four wheels and an engine.
//----------
//Car object: YourApplication.ConvertibleCar
//Four wheels and an engine.
//----------
//Car object: YourApplication.Minivan
//Four wheels and an engine.
//Carries seven people.
Console.Read();
}
}
#endregion[WhenToUseNewOverride]