关于父类,子类,继承,和构造函数的那些事

 

一些非常非常基础的知识,今天在学习装饰者模式的时候,半路调试出来的,总结一下

 

1.

这一段代码比较简单,而且已经被我删了,就不再敲一次出来了.大家可以自己试一试.

我们有一个父类People.父类有两个构造函数,一个有参构造函数,一个无参的构造函数.

一个类Teacher.它继承于People.当我们实例化new一个Teacher出来时,它出发生两件事.

第一件事:People的无参构造函数会被执行,

第二件事:Teacher的构造函数会被执行(如果我们有写Teacher的构造函数的话)

(提醒:父类构造函数不会继承给子类)

 

 

2.

在1.之上,我们继续.

把People的无参构造函数删掉,此时编译不通过.在Teacher里面提示:People不包含采用"0"个参数的构造函数.

这里我隐约感觉到,实例化子类时,是不是父类也会被实例化呢..

既然这样改一改,为子类Teacher加一个无参构造函数,并在构造函数后面用Base显式调用父类的另外一个有参构造函数如

简单代码如下:

 

 1 class People
 2     {
 3         public People(string str)
 4         {
 5             Console.WriteLine("str");        
 6         }
 7     }
 8 class Teacher
 9     {
10         public Teacher():base("显式调用父类的构造函数")
11     }
代码

 

此时编译通过,而且控制台成功输出"显式调用父类构造函数",我们可以得出几点:

1.子类实例化时,系统会默认调用父类的无参构造函数,

2.若父类没有无参构造函数让系统默认调用时,这时它会编译不通过,我们可以用base时显式调用父类带参的构造函数,才能通过编译.

另外,通过反编译工具DotNET Reflector反编译查看,我们写一个普通类时,若我们没有为这个类编写构造函数,那么系统一定会为这个类隐式添加一个无参的构造函数..

所以一般继承了一个父类,却编译不通过,回头看看是不是这个父类没有无参的构造函数.

 

3.

 第三点就是今天的主菜了.

当实例化子类时,其实父类也一样被实例化出来了!只是没有被缓存起来而已..

证明代码如下,

 

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Runtime.Serialization.Formatters.Binary;
 7 using System.IO;
 8 
 9 namespace Test
10 {
11     class Program
12     {
13         public static Zm zm;
14 
15         public static void Main(string[] args)
16         {
17             zm = new Zm();
18             MrWong mw = new MrWong("实例化一个MrWong");
19             zm.people.Show();
20             Console.ReadKey();            
21         }
22     }
23 
24     class Zm
25     {
26         public People people;
27     }
28 
29 
30     class People
31     {
32         private string name ;
33 
34         //把这个类缓存到Zm的people里
35         public People(string name)
36         {
37             Console.WriteLine("People构造");
38             Console.WriteLine(name);
39             this.name = name;
40             Program.zm.people = this;
41         }
42 
43         
44         public void Show()
45         {
46             Console.WriteLine(name+"创造");
47         }
48     }
49 
50     class Teacher:People
51     {
52         //显式调用父类的代参构造函数,并将参数往下传
53         public Teacher(string name)
54             : base(name)
55         {
56             Console.WriteLine("Teacher构造");
57         }
58     }
59 
60     class MrWong:Teacher
61     {
62         //显式调用父类的代参构造函数,并将参数往下传
63         public MrWong(string name)
64             : base(name)
65         {
66             Console.WriteLine("MrWong构造");
67         }
68     }
69 }
代码

 运行结果是

 

第一行是爷爷类的构造函数

第二行是爷爷类的构造函数参数

第三行是父类的构造函数

第四行是子类的构造函数

第五行是被缓存实例的爷爷类里面的函数.

 

第一次写博客,想尽量把思路描述清晰,比较啰嗦,接受各路英雄指导哈....

posted @ 2015-03-30 20:04  Dr.jarvis  阅读(216)  评论(0)    收藏  举报