写出程序的输出结果:
public class A
{
public virtual void Fun1(int i)
{
Console.WriteLine(i);
}
public void Fun2(A a)
{
a.Fun1(1);
Fun1(5);
}
}
public class B : A
{
public override void Fun1(int i)
{
base.Fun1 (i + 1);
}
public static void Main()
{
B b = new B();
A a = new A();
a.Fun2(b);
b.Fun2(a);
}
}
结果是2,5,1,6。
这是一个很古老的面试题,我当时在一家公司面试时也遇到了这个问题,当时我的结果是1,5,2,5。也就是最后一个错了,就这个问题
引起了我的思考,我觉得我在写程序时忽视了一个很重要的问题。那就是单步调试的作用。
其实我们应该在写程序时经常用一下单步调试
,这样能让我们能更好地理解程序的执行过程,这样就不会像很多网友说的做这个题做的头疼。那么现在来分析一下这个题目吧,
程序首先从Main()执行;——>B b = new B();如果B中有构造函数就再去执行它。——>A a = new A();如果A
中有构造函数就再去执行它。——>a.Fun2(b);到这时A中的public void Fun2(A a)把b传进去就得到b.Fun1(1);Fun1(5);程序就再跳到
B中public override void Fun1(int i)得第一个结果2,再执行Fun1(5);跳到A中public virtual void Fun1(int i)得第二个结果5
那么a.Fun2(b);就执行完了。再执行b.Fun2(a);程序又会在基类中找到public void Fun2(A a),得到a.Fun1(1);Fun1(5);
就会执行a.Fun1(1)得到结果1,最后一点要注意,我先也错过,这里Main()中是b.Fun2(a);所以会跳到B中执行public override void Fun1(int i)
得到结果6。所以结果是:2,5,1,6
所以我们在写程序时不要想当然认为程序会怎么执行,我们分析程序结果时一定要了解程序的执行过程,这样就灰觉得很简单
那么我们不妨在写完每一个程序后都看看它的执行过程。这样我们能更清楚地了解程序。
留个问题给大家吧:
public abstract class A
{
public A()
{
Console.WriteLine('A');
}
public virtual void Fun()
{
Console.WriteLine("A.Fun()");
}
}
public class B: A
{
public B()
{
Console.WriteLine('B');
}
public new void Fun()
{
Console.WriteLine("B.Fun()");
}
public static void Main()
{
A a = new B();
a.Fun();
}
}
看看程序时怎么执行的,是先调用A的构造函数还是B的呢?