C#教学第23讲类的构造2(学习笔记)

第23讲类的构造2

  视频讲师:陈广老师

    大家好,今天我们接着上节课的内容继续讲构造器。这节课我们主要讲讲在类的继承中构造器的使用,我们首先讲一讲继承。

22

    这是一个UML图,在UML图中类用一个方框表示,由图可以看的很清楚有A和B两个类,A类的UML图中显示有成员变量和成员方法。空心的三角箭头由B类指向A类,意味着B类是由A类继承而来,A类是B类的父类或者又称A类是B类的基类。B类继承至A类就意味着B类拥有A类部分特征,下面我们用C#代码来表示这幅图。

    以上代码就等效于上面的UML图。我们来看一下下面的代码:

 class2.cs类

在类A和类B中各自定义了自己的无参构造器,在入口函数中实例化一个B的对象,结果是什么呢?结果如图:

23

    我们看类B在实例化的过程中首先执行了它父类A的无参构造器,所以先打印出“我是类A的无参构造器”文字,接着才是执行自己的无参构造器,打印出“我是类B的无参构造器”文字。换句话说,在一个类进行实例化的过程中,它首先会执行父类的无参构造器。

    如果类A有2个构造器,类B在实例化的过程中,它会执行哪一个呢?

 

运行程序执行的结果是和上一次一样的,它执行的还是类A的无参构造器,我们再给类B重载一个构造器,在入口函数中我们调用类B的有参构造器。

编译代码执行程序,结果如下:

23

    我们看,实践证明始终是调用类A的无参构造器,这里有一个很有意思的现象,假如我们把类A的无参构造器屏蔽(注释)掉,然后在运行程序,这个的时候编译不能得到通过,提示错误“A方法没有采用0个参数的重载”,也就是说类B在调用它的构造器的时候,它必须首先调用类A的无参构造器。这时候大家可能会问了,上节课不是说过,一个类会自动生成一个无参构造器(请看上节课的内容),现在为什么不会自动生成了呢?

   好,我们来做一下实验,代码如下:

 

编译下代码,我们用反编译ildasm工具来看下结果:

23

    由图可知,类A自动生成了无参构造器,跟我们上节课讲的完全吻合。好,我们再改下代码,在类A中增加一个有参的构造器。

编译下代码,我们再用反编译ildasm工具来看下结果:

23

    我们看,由于类A声明了一个有参的构造器,这个时候它就不会再自动生成无参构造器,现在就可以解释刚才代码不能执行了。当类B的实例被创建的时候,它首先要找到父类A里面的无参构造器并执行它,然后才执行自己的构造器,如果找不到呢编译器就会报错。

    现在呢我们可以得出一个结论,写一个类的时候,如果要写带参的构造器,最好就跟上一个无参的构造器,即使这个无参构造器什么都不做,我们也要养成良好的习惯把它写上去。

    这时候有人可能会问了,如果我想在类B中执行类A中指定的构造器该怎么办呢?这个非常简单,使用base关键字就可以了:

编译代码,执行结果如图:

23

在类中,经常使用到this和base,请大家记住。

    之前我们所讲的都是实例构造器,现在我们来讲一下静态的构造器(static constructor)。

    静态构造函数是实现对一个类进行初始化的方法成员。它一般用于对静态数据的初始化。静态构造函数不能有参数,不能有修饰符而且不能被调用,当类被加载时,类的静态构造函数自动被调用。

    我们再说一下静态构造器的的几个准则:

    1.在一个程序的执行过程中,静态构造器最多只执行一次。

    2.静态构造器在类的静态成员初始化之后执行。或者讲编译器会将静态成员初始化语句转换成赋值语句放在静态构造器执行的最开始。

    3.静态构造器在任何类的静态成员被引用之前执行。

    4.静态构造器在任何类的实例变量被分配之前执行。

 好,我们对这些一一做讲解,代码如下:

  

编译后用反编译工具查看:

23

     我们来看一下,这时候自动生成了2个构造器,第一个构造器(.ctor)是继承至Object的无参构造器,第二个构造器(.cctor)就是前面图标上有个S的,它就是一个静态的构造器,里面将i赋值100。这说明什么呢?就是准则的第二个,编译器会将静态成员初始化语句转换成赋值语句放在静态构造器执行的最开始。

    也就是说,这个类为了给这个静态成员初始化,特地创建了一个静态构造器。为了了验证这一点,我们不对i赋初值。大家可以自己实验一下,编译后发现没有对静态变量赋初值,静态构造器也就没有了。

    好,接下来我们手动声明一个构造器:

编译代码,我们来看一下结果:

23

    我们看,虽然我们没有对类A进行实例化,但是我们调用了它的静态变量i,也就意味着我们使用了类A。这时候类A被加载了,所以静态构造函数也被调用,所以打印出了“我是类A的静态构造函数”这一行,接着才是打印出i的值“100”。记住,静态构造器是在i被使用之前被加载的。接下来我们对A进行实例化,看看是什么结果:

 

 编译代码,我们来看一下结果:

我是类A的静态构造器

我是类A的无参构造器

    可以看出,首先调用了类A的静态构造器,然后才调用了类A的实例构造器。

    我们再继续修改代码,再实例化一个类A,结果是什么呢?

编译代码,我们来看一下结果:

我是类A的静态构造器

我是类A的无参构造器

我是类A的无参构造器

    我们看静态构造器只调用了一次,它没有调用2次,这也印证了在一个程序的执行过程中,静态构造器最多只执行一次。

    静态构造器的主要作用就是对类的静态成员进行初始化,好今天就讲到这里。

由快乐乔巴听课摘写笔记

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值