|
|
20 Module 10: Inheritance in C#
Practice: Implementing Methods
class A {
public virtual void M() { Console.Write("A" ; }
}
class B: A {
public override void M() { Console.Write("B" ; }
}
class C: B {
new public virtual void M() { Console.Write("C" ; }
}
class D: C {
public override void M() { Console.Write("D" ; }
static void Main() {
D d = new D(); C c = d; B b = c; A a = b;
d.M(); c.M(); b.M(); a.M();
}
}
class A {
public virtual void M() { Console.Write("A" ; }
}
class B: A {
public override void M() { Console.Write("B" ; }
}
class C: B {
new public virtual void M() { Console.Write("C" ; }
}
class D: C {
public override void M() { Console.Write("D" ; }
static void Main() {
D d = new D(); C c = d; B b = c; A a = b;
d.M(); c.M(); b.M(); a.M();
}
}
To practice the use of the virtual, override and new keywords, work through
the code displayed on this slide to figure out what the output of the code will be.
The Solution
After the program executes, it will display the result DDBB to the console.
Program Logic
There is only one object created by the program. This is the object of type D
created in the following declaration:
D d = new D( );
The remaining declaration statements in Main declare variables of different
types that all refer to this one object:
n c is a C reference to d.
n b is a B reference to c, which is reference to d.
n a is an A reference to b, which is reference to c, which is reference to d.
Then come the four expression statements. The following text explains each
one individually.
The first statement is
d.M( )
This is a call to D.M, which is declared override and hence is implicitly virtual.
This means that at run time the compiler calls the most derived implementation
of D.M in the object of type D. This implementation is D.M, which writes D to
the console.
Module 10: Inheritance in C# 21
The second statement is
c.M( )
This is a call to C.M, which is declared virtual. This means that at run time the
compiler calls the most derived implementation of C.M in the object of type D.
Since D.M overrides C.M, D.M is the most derived implementation, in this
case. Hence D.M is called, and it writes D to the console again.
The third statement is
b.M( )
This is a call to B.M, which is declared override and hence is implicitly virtual.
This means that at run time the compiler calls the most derived implementation
of B.M in the object of type D. Since C.M does not override B.M but
introduces a new method that hides C.M, the most derived implementation of
B.M in the object of type D is B.M. Hence B.M is called, and it writes B to the
console.
The last statement is
a.M( )
This is a call to A.M, which is declared virtual. This means that at run time the
compiler calls the most derived implementation of A.M in the object of type D.
B.M overrides A.M, but as before C.M does not override B.M. Hence the most
derived implementation of A.M in the object of type D is B.M. Hence B.M is
called, which writes B to the console again.
This is how the program generates the output DDBB and writes it to the console.
In this example, the C and D classes contain two virtual methods that have the
same signature: the one introduced by A and the one introduced by C. The
method introduced by C hides the method introduced by A. Thus, the override
declaration in D overrides the method introduced by C, and it is not possible for
D to override the method introduced by A. |
|