1: class A
2: {3: public int num;
4: public A() { Console.WriteLine(".ctor() of A"); }
5: public A(int num)
6: {7: Console.WriteLine(".ctor(int) of A");
8: this.num = num;
9: }10: ~A() { Console.WriteLine("Finalize of A"); }
11: }12: class B : A
13: {14: public B(int num) { Console.WriteLine(".ctor(int) of B"); }
15: ~B() { Console.WriteLine("Finalize of B"); }
16: } 17: 18: static void Main(string[] args)
19: {20: B b = new B(10);
21: Console.WriteLine(b.num);22: b = null;
23: GC.Collect(); 24: GC.WaitForPendingFinalizers(); 25: Console.ReadLine(); 26: }输出结果?
.ctor() of A
.ctor(int) of B
0
Finalize of B
Finalize of A
上面这个题目考查的是构造函数和析构函数执行顺序的问题。
构造函数的执行顺序是:父类->子类,即先执行父类的构造函数,再执行子类的构造函数。多层继承总是从最上层的父类开始。
析构函数的执行顺序是:子类->父类,即先执行子类的析构函数,在执行父类的析构函数。
根据这个原则来解答这个题目:
1、子类B继承了父类A,所以在实例化B时,先执行父类A的构造函数。
父类A有两个构造函数,应该执行哪一个呢?
如果子类B的构造函数继承时没有指定继承父类A的构造函数,默认执行父类A的默认构造函数。
所以输出为:
.ctor() of A
.ctor(int) of B
不会执行父类A带参的构造函数,那什么情况下会执行父类A带参的构造函数呢?只要把子类B的构造函数修改一下就可以了。
1: public B(int num):base(num) { Console.WriteLine(".ctor(int) of B"); }
改成这样后输出结果为:
.ctor(int) of A
.ctor(int) of B
2、子类B继承了父类A的变量num,所以子类B可以使用变量num。但是子类B实例化时默认执行的是父类A的默认构造函数,所以变量num没有赋值,所以Console.WriteLine(b.num);这段代码输出结果为:0
3、析构函数的执行比较简单,按照“子类->父类”原则,输出结果为:
Finalize of B
Finalize of A
GC是.net的垃圾收集器,自动进行内存资源的回收,一般不需要程序员关心资源回收的问题。当一个对象没有任何引用的时候就可以被回收。一个对象可以被回收并不意味着一定会被立即回收,GC会选择时机进行回收。但是可以调用GC.Collect();来立即回收。对于垃圾回收机制以后再学习。
浙公网安备 33010602011771号