using System;
public class ParentClass
{
public ParentClass()
{
Console.WriteLine("Parent Constructor.");
}
public void print()
{
Console.WriteLine("I'm a Parent Class.");
}
}
public class ChildClass : ParentClass
{
public ChildClass()
{
Console.WriteLine("Child Constructor.");
}
public static void 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 fromParentClass.
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 theprint() method is called. ChildClass does not have its own print() method, so it uses the ParentClass print() 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;
public class Parent
{
string parentString;
public Parent()
{
Console.WriteLine("Parent Constructor.");
}
public Parent(string myString)
{
parentString = myString;
Console.WriteLine(parentString);
}
public void print()
{
Console.WriteLine("I'm a Parent Class.");
}
}
public class Child : Parent
{
public Child() : base("From Derived")
{
Console.WriteLine("Child Constructor.");
}
public new void print()
{
base.print();
Console.WriteLine("I'm a Child Class.");
}
public static void 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. The colon, ":", and keyword base call the base class constructor with the matching parameter list. If the code had not appended base("From Derived") to the Derived constructor, the code would have automatically calledParent(). The first line of output shows the base class constructor being called with the string "From Derived".
Sometimes you may want to create your own implementation of a method that exists in a base class. The Child class does this by declaring its own print() method. The Child print()method hides the Parent print() method. The effect is the Parent print() method will not be called, unless we do something special to make sure it is called.
Inside the Child print() method, we explicitly call the Parent print() 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 Child print() method is on output lines 3 and 4.
Another way to access base class members is through an explicit cast. This is done in the last statement of the Child class Main() method. Remember that a derived class is a specialization of its base class. This fact allows us to perform a cast on the derived class, making it an instance of its base class. The last line of output 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.
class Animal
{
public Animal()
{
HttpContext.Current.Response.Write("Animal constructor");
}
public void Greet()
{
HttpContext.Current.Response.Write("Animal says Hello");
}
public void Talk()
{
HttpContext.Current.Response.Write("Animal talk");
}
public virtual void Sing()
{
HttpContext.Current.Response.Write("Animal song");
}
}
class Dog : Animal
{
public Dog()
{
HttpContext.Current.Response.Write("Dog constructor");
}
public new void Talk()
{
HttpContext.Current.Response.Write("Dog talk");
}
public override void Sing()
{
HttpContext.Current.Response.Write("Dog song");
}
public static void Main()
{
Animal a2 = new Dog();
a2.Talk();
a2.Sing();
a2.Greet();
}
}
We have an object of type Animal, but it references an object of type Dog.
Thus you can see the base class constructor getting called first followed by the derived class constructor.
Now we call Talk() and find that the method that's executed is the base class method.
That's not surprising when you consider that the object was declared to be of the base type which in our case is Animal.
Now when we call Sing(), we find that the derived class method has got called.
This is because in the base class the method is prototyped as public virtual void Sing() and in the derived class we have overridden it by using public override void Sing().
In C#, we need to explicitly use the override keyword as opposed to C++ where we didn't have to do that.
And finally when we call Greet() the base class method gets called and this is not confusing at all specially since the derived class has not even implemented the method.
class Color
{
public virtual void Fill()
{
HttpContext.Current.Response.Write("Fill me up with color");
}
public void Fill(string s)
{
HttpContext.Current.Response.Write("Fill me up with " + s);
}
}
class Green : Color
{
public override void Fill()
{
HttpContext.Current.Response.Write("Fill me up with green");
}
public static void Main()
{
Green g1 = new Green();
g1.Fill();
g1.Fill("violet");
}
}
---------------------------------------------------
class Software
{
public Software()
{
m_x = 100;
}
public Software(int y)
{
m_x = y;
}
protected int m_x;
}
class MicrosoftSoftware : Software
{
public MicrosoftSoftware()
{
HttpContext.Current.Response.Write(m_x + "
");
}
}
class AstuteSoftware : Software
{
//Here I am telling the compiler which
//overload of the base constructor to call
public AstuteSoftware(int y)
: base(y)
{
HttpContext.Current.Response.Write(m_x + "
");
}
//Here we are telling the compiler to first
//call the other overload of the constructor
public AstuteSoftware(string s, int f)
: this(f)
{
HttpContext.Current.Response.Write(s + "
");
}
}
protected void Page_Load(object sender, EventArgs e)
{
MicrosoftSoftware m1 = new MicrosoftSoftware();
//MicrosoftSoftware m2 = new MicrosoftSoftware(300); will not compile
AstuteSoftware du1 = new AstuteSoftware(50); // 50
AstuteSoftware du2 = new AstuteSoftware("test", 75); // 75 test
}
MicrosoftSoftware m2 = new MicrosoftSoftware(300); will not compile
The base class had two overloaded constructors. One that took zero arguments and one that took an int.
In the derived class we only have the zero argument constructor. Constructors are not inherited by derived classes.
Thus we cannot instantiate a derived class object using the constructor that takes an int as parameter.
As you will deduce from the output we got, the base class constructor that called was the default parameter-less constructor.
Now take a look at this second derived class.
Download Code
No comments:
Post a Comment