13.Inheritance
Inheritance is one of the primary concepts of object-oriented programming. It allows you to reuse existing code. Through effective employment of reuse, you can save time in your programming.
Listing 8-1. Inheritance: BaseClass.cs
using System; publicclass ParentClass { public ParentClass() { Console.WriteLine("Parent Constructor."); } publicvoid print() { Console.WriteLine("I'm a Parent Class."); } } publicclass ChildClass : ParentClass { public ChildClass() { Console.WriteLine("Child Constructor."); } publicstaticvoid Main() { ChildClass child = new ChildClass(); child.print(); } }
Output:
Parent Constructor.
Child Constructor.
I’m a Parent Class.
Listing 8-1 shows two classes. The top class is named ParentClass and the main class is called ChildClass. What we want to do is create a child class, using existing code from ParentClass.
First we must declare our intention to use ParentClass as the base class of ChildClass. This is accomplished through the ChildClass declaration public class ChildClass : ParentClass. The base class is specified by adding a colon, “:”, after the derived class identifier and then specifying the base class name.
Note: C# supports single class inheritance only. Therefore, you can specify only one base class to inherit from. However, it does allow multiple interface inheritance, a subject covered in a later lesson.
ChildClass has exactly the same capabilities as ParentClass. Because of this, you can also say ChildClass “is” a ParentClass. This is shown in the Main() method of ChildClass when the print() method is called. ChildClass does not have its own print() method, so it uses the ParentClassprint() method. You can see the results in the 3rd line of output.
Base classes are automatically instantiated before derived classes. Notice the output from Listing 8-1. The ParentClass constructor executed before the ChildClass constructor.
Listing 8-2. Derived Class Communicating with Base Class: BaseTalk.cs
using System; publicclass Parent { string parentString; public Parent() { Console.WriteLine("Parent Constructor."); } public Parent(string myString) { parentString = myString; Console.WriteLine(parentString); } publicvoid print() { Console.WriteLine("I'm a Parent Class."); } } public class Child : Parent { public Child() : base("From Derived") { Console.WriteLine("Child Constructor."); } publicnewvoid print() { base.print(); Console.WriteLine("I'm a Child Class."); } publicstaticvoid Main() { Child child = new Child(); child.print(); ((Parent)child).print(); } }
Output:
From Derived
Child Constructor.
I’m a Parent Class.
I’m a Child Class.
I’m a Parent Class.
Derived classes can communicate with base classes during instantiation. Listing 8-2 shows how this is done at the child constructor declaration.print() method hides the Parentprint() method. The effect is the Parentprint() method will not be called, unless we do something special to make sure it is called.
Inside the Childprint() method, we explicitly call the Parentprint() method. This is done by prefixing the method name with “base.”. Using the base keyword, you can access any of a base class public or protected class members. The output from the Childprint() from Listing 8-2 shows the Parentprint() method was indeed executed.
Notice the new modifier on the Child class print() method. This enables this method to hide the Parent class print() method and explicitly states your intention that you don’t want polymorphism to occur. Without the new modifier, the compiler will produce a warning to draw your attention to this. See the next lesson for a detailed discussion of polymorphism.
In summary, you know how to create a derived/base class relationship. You can control instantiation of your base class and call its methods either implicitly or explicitly. You also understand that a derived class is a specialization of its base class.