关于类、继承、抽象方法、构造函数等求输出结果的一些面试题

有好多面试的时候写几个类互相继承,里面有抽象方法,然后各种实例化,搞的晕头转向的,在这里稍微总结下,以后慢慢地补充:

1:

 1 class A
 2     {
 3         public A()
 4         {
 5 
 6             PrintFields();
 7         }
 8         public virtual void PrintFields() { }
 9     }
10     class B : A
11     {
12         int x = 1;
13         int y;
14         public B()
15         {
16             y = -1;
17         }
18         public override void PrintFields()
19         {
20             Console.WriteLine("x={0},y={1}", x, y);
21         }
22     }
View Code

当使用new B()创建B的实例时,产生什么输出?

这个应该算是简单的,但是也有很多对于继承构造函数的执行顺序不清的弄得苦不堪言。

分析:

  当new B()输出的为X= 1 ,Y = 0;
   1、在new B()是会先调父类即A的构造函数,这时会执行PrintFields();方法,因为PrintFields方法为虚拟方法,在子类中重写的该方法,所在实际执行的为B中的PrintFields方法。
   2、为什么Y=0?这是因在调用的是父类方法,子类的中的Y还没初始会,系统自己赋值为0。

 

2:

下面这一个问题是在第一个的基础上进行扩展下

 1  class A
 2     {
 3         public A()
 4         {
 5 
 6             PrintFields();
 7         }
 8         public virtual void PrintFields() { }
 9     }
10     class B : A
11     {
12         int x = 1;
13         public int y;
14         public B()
15         {
16             y = -1;
17         }
18         public override void PrintFields()
19         {
20             Console.WriteLine("x={0},y={1}", x, y);
21         }
22     }
23     public class C
24     {
25 
26         public static void Main()
27         {
28             B b = new B();
29             Console.WriteLine("Y={0}", b.y);
30             Console.Read();
31 
32         }
33     }
View Code

分析:

  答案为:X=1,Y = 0
              Y = -1

至于为啥,各位打个断电调试下就知道了

 

3:

下面这个题各位不知道有没有犯迷糊的

 1 static Person GetPerson()
 2         {
 3             Person p = new Person();
 4             p.Age = 8;
 5             try
 6             {
 7                 p.Age++;
 8                 return p;
 9             }
10             finally
11             {
12                 p.Age++;
13             }
14          }
15 static int stac()
16         {
17             int i = 8;
18             try
19             {
20                 i++;
21                 return i;
22 
23             }
24             finally
25             {
26                 i++;
27             }
28         }
29 
30 public static void Main()
31         {
32             Console.WriteLine(GetPerson().Age);
33             Console.WriteLine(stac());
34         }    
View Code

这个破题,真不知道该说啥了,直接公布结果:第一个为10,第二个为9

 

4:

上面的懂了,请看下一题

 1     class A
 2     {
 3         public static int X;
 4         static A()
 5         {
 6             X = B.Y + 1;
 7         }
 8     }
 9     class B
10     {
11         public static int Y = A.X + 1;
12         static B() { }
13         static void Main()
14         {
15             Console.WriteLine("X={0},Y={1}", A.X, B.Y);
16             Console.ReadKey();
17         }
18     }
View Code

答案是 1,2

看一下别人写的结论吧,我觉得说的听明白了,自己就不再多说了:

因为执行的时候,首先从程序的入口点(就是Main())找起,因为Main在类B中,所以从B类开始加载。执行顺序大致是这样的:
(用到一个类的时候是先对其静态变量初始化,然后调用他的静态构造函数)
(类的静态构造函数只在加载类的时候由系统调用一次且只此一次)
1.初始化B类的静态变量 Y,系统先给他一个默认值(此处是0),然后再执行他的初始化赋值语句public static int Y = A.X + 1;
2.执行这条语句的时候因为用到了A.X,所以遇到A的时候去加载类A,顺序一样,先是执行A的静态变量X的初始化工作public static int X;因为没有对其赋值的操作,所以X就是系统给他的默认值0;然后调用A的静态构造函数(B那里也是先初始化静态变量,然后才调用静态构造函数,因为B初始化静态变量的时候用到了A所以才会跳到A来,不然的话B那边也是初始化静态变量之后系统紧接着就会调用B的静态构造函数);
3,A的静态构造函数中执行X = B.Y + 1;可以知道,此时B.Y已经有了一个系统给他的默认值0,所以此处就是X=0+1;现在X就是1了
4,X那边都完工了,回到刚才跳转X的地方继续执行,就是继续执行Y = A.X + 1;毫无疑问此时是Y=1+1;至此,B的静态变量初始化完成了。
5,B的静态变量初始化完成了那紧接着就是系统调用B的静态构造函数,此处什么也不执行。
6.输出结果1,2
 
posted @ 2014-03-12 09:48  贾锡安  阅读(298)  评论(0编辑  收藏  举报