SCI论文(www.lunwensci.com):
摘要:本文围绕继承关系中构造函数的调用,对无参构造函数和有参构造函数调用过程和实现方法进行深入剖析,对构造函数调用中存在的典型问题进行了举例说明。
关键词:基类和派生类;构造函数;构造函数调用
Analysis of Constructor Calling Process under C#Inheritance
HUANG Xiaohua
(Jiangxi Vocational and Technical College,Nanchang Jiangxi 330013)
【Abstract】:This article focuses on the call of constructors in inheritance relations,deeply analyzes the call process and implementation methods of parameterless constructors and constructors with parameters,and gives examples of typical problems in constructor call.
【Key words】:base class and derived class;constructor;constructor call
0引言
继承中的构造函数根据所处类的位置,可分为基类中的构造函数和派生类中的构造函数。这里从基类中的构造函数出发,根据基类中的构造函数是否带参数,将基类构造函数分为基类中无参数构造函数调用和基类中有参构造函数的调用,以下针对这两种情况,对继承中构造函数的调用和实现过程进行全面分析。
1继承中构造函数调用顺序
在继承关系中,类可以层层派生,如,类A可以派生出类B,类B可以派生出类C类……类层层派生时,类中的构造函数调用顺序是怎样的呢?C#中规定,继承中构造函数的调用是从最顶层的父类开始,向子类方向依次顺序调用下一级的构造函数。在以上类的派生中,应最先调用父父类即A类中的构造函数,再调用父类即B类中的构造函数、最后再调用当前类即C类中自己的构造函数。
2基类中无参构造函数调用过程分析
基类中无参构造函数,指的是在基类存中在一个在声明时没有指定参数的构造函数,或者是该基类不存在无参构造函数,但在创建类对象时,由系统自动创建一个无参构造函数。
2.1基类中无参构造函数隐式调用
在C#继承机制中,基类中无参构造函数系统将自动隐式调用,具体如下:在创建基类的派生类对象时,系统先自动调用基类中的无参构造函数(如果基类中不存在无参构造函数,系统将为其创建一个不带参数的空的构造函数),再自动调用派生类自己的构造函数(具体调用派生类哪个构造函数,根据创建派生类对象时传递给构造函数的参数而定)。
2.2基类中无参构造函数调用过程分析
以下通过具体例子来分析继承中基类无参构造函数调用过程。程序执行过程分析:在Main入口方法中,创建派生类B的对象b,在创建派生类对象时,系统先自动调用基类A中的无参构造函数A,然后再自动调用派生类自己的构造函数。此处派生类有两个构造函数,由于在创建派生类对象时向其构造函数传递了一个整型参数,根据函数重载的知识[1],将执行派生类中带一个参数的构造函数,而派生类中无参构造函数在此处并不会执行(见图1)。
假设程序中删除类A中的构造函数A,则系统在创建派生类对象b时,也会自动为类A创建一个不带参数的空的构造函数并调用,然后再调用派生类自己的带参构造函数。
3基类中有参构造函数调用过程分析
基类中有参构造函数指的是在基类中存在一个或多个带有参数的构造函数,这些构造函数或是带有不同个数的参数、或是带有不同的参数类型。在创建类对象时,依据构造函数重载的知识,系统会将根据传递的参数个数或参数类型来决定调用哪个构造函数[2]。
3.1基类中有参构造函数必须显式调用在C#继承机制中,基类中带有参数的构造函数必须显式调用,显式调用通过base关键字实现。格式是:在派生类构造函数后加上:base(参数……)。具体过程如下:在创建派生类对象时,先调用基类中的构造函数,在调用基类中的构造函数时,将派生类构造函数所接受到的参数通过base传递给基类的构造函数。如果基类有多个构造函数,将根据base传递的参数进行重载;执行完基类构造函数后,再调用派生类自己的构造函数[3]。注意:通过base传入基类的参数,需要与基类参数列表中的参数类型一致,否则会造成基类构造函数重载时参数类型不匹配的问题。
3.2基类中有参构造函数调用过程分析
以下通过具体例子来分析继承中基类有参构造函数调用过程。程序执行过程分析:首先执行类Program中的Main方法,创建派生类B的实例对象b,并将实参2和3传递给派生类构造函数。根据传递的参数,系统自动重载派生类B中第三个构造函数(带两个整型参数的构造函数B)。在执行该派生类构造函数前先调用基类中构造函数,由于被重载的构造函数使用了base关键字,因此将base中的参数传递给基类构造函数,基类根据base传递过来的参数,自动重载基类中第二个有参构造函数(带两个参数的构造函数)[4],即输出2和3两数乘积6。接下来再调用派生类自己的构造函数(带两个整型参数的构造函数B),即输出2和3两数和5,程序最终运行结果为“6,5”(见图2)。
假设在定义构造函数时,为构造函数指定了base关键字,因此系统显式调用基类中所有的构造函数,并根据base中传递的参数,重载基类中符合条件的构造函数。
假设定义派生类第三个构造函数时,如没有通过冒号指定base关键字,即将派生类B中第三个构造函数:base(a,b)部分删除,则程序的运行结果又是怎样呢?如果没有指定base关键字,在执行该派生类构造函数前,会先调用基类中无参构造函数,即A类中第一个无参构造函数会执行,程序输出“基类无参构造函数”,然后再调用派生类构造函数,即输出2和3两数的和5,程序最终运行结果为“基类无参构造函数,5”。
假设定义派生类第三个构造函数时,如果base关键字括号内不带参数,即在定义派生类B第三个构造函数时,将:base(a,b)部分改为:base(),则程序的运行结果又是怎样呢?如果没有为base关键字指定参数,在执行该派生类构造函数前,同样会先调用基类中构造函数,由于base不带参数,因此,会自动重载基类中不带参数的构造函数。程序最终运行结果仍为:“基类无参构造函数,5”。
如修改类Program的Main方法,使其创建派生类对象时,向派生类的构造函数传递一个参数,即将原语句B b=new B(2,3)修改为B b=new B(2),则程序的运行结果又是怎样呢?程序将重载派生类中带一个参数的构造函数(即B类中第二个构造函数),并将实参2传递给该构造函数。由于该派生类构造函数没有使用base关键字[5],因此,会先调用基类中不带参数的构造函数,输出“基类无参构造函数”;然后再执行派生类带一个参数的构造函数,输出2,程序最终运行结果仍为:“基类无参构造函数,2”。
如修改类Program的Main方法,使其创建派生类对象时,使用不带参数的构造函数,即将原语句B b=new B(2,3)修改为B b=new B(),则程序的运行结果又是怎样呢?程序将重载派生类中不带参数的构造函数(即B类中第一个构造函数)。由于该构造函数没有使用base关键字,所以系统自动调用基类无参构造函数,先输出“基类无参构造函数”;然后再执行派生类自己的无参构造函数,再输出“派生类无参构造函数”。
4继承中构造函数调用问题及解决办法
4.1构造函数调用问题1:基类中不存在无参构造函数问题在例2中,将基类A中无参构造函数移去,即删除public A(){Console.WriteLine("基类无参构造函数");}此部分代码后,派生类B中定义的前两个不带base关键字的构造函数(第一个无参构造函数和第二个带一个参数的构造函数)会报错,报错的原因是“基类中不包0个参数的构造函数”。为什么会出现此类错误?应如何解决?
错误原因:在继承关系下创建派生类对象时,如果派生类中的构造函数没有指定base关键字,则派生类会先调用基类中无参构造函数。如,此处派生类B中的前两个构造函数public B()和public B(int a)都没有指定base关键字,因此,他们会自动先调用基类中无参构造函数;如果在父类中已经存在有参构造函数,那么系统将不会自动创建无参构造函数,所以在派生类的构造函数中再去调用基类的无参构造函数时就会出现编译上的错误。如,此处基类A已存在一个有参构造函数,系统不会再去自动创建无参构造函数,因此当派生类B中的public B()和public B(int a)两个派生构造函数再自动去调用基类A中的无参构造函数时,由于基类不存在无参构造函数,而出现编译报错:“基类中不包0个参数的构造函数”。
解决办法有两个,第一种方法是:在基类中加入无参构造函数。即将删除的public A(){Console.WriteLine(“基类无参构造函数”);}代码重新添加到基类中。这样派生类B中前两个不带base关键字的构造函数在自动调用基类中无参构造函数时就不会出错。
第二种方法是:在派生类中通过指定base关键字显式调用基类中的构造函数。如,此处给派生类B前两个构造函数加上base关键字,显式调用基类A中有参构造函数。即在派生类B中的public B()和public B(int a)两个构造函数后都加上:base(参数1,参数2),使其显式调用基类A中的带两个参数的有参构造函数,同样可解决此问题。
4.2构造函数调用问题2:base关键字指向问题
在例2中,修改派生类B第二个构造函数,将public B(int a)改为public B(int a):base(int a),则此处会出现编译上的错误,错误原因为:基类中不包含1个参数的构造函数。为什么会出现此类错误?应如何解决?错误原因:派生类构造函数base关键字后只带一个参数,因此base指向的是基类中带一个参数的构造函数,而基类中不存在带一个参数的构造函数,因此会出现错误。
解决办法同样有两个,第一种方法是:因基类A中有带两个参数的构造函数,因此可为base关键字指定带两个参数的构造函数调用,即修改为base(参数1,参数2)即可。
第二种方法是:因基类A中有不带参数的构造函数,因此可将base关键字省去,让系统自动调用基类中的无参构造函数;或者将base关键字中的参数省去,让base指向基类中无参构造函数。
5结语
C#继承关系下,构造函数是不可继承的,但可通过调用来完成对象的初始化工作。在调用继承关系下的构造函数时,需从最顶层的基类开始,最后再调用当前派生类自己的构造函数。对于基类中无参构造函数,系统将隐式自动调用;对于基类中有参构造函数,必须使用base关键字显式调用,并且通过base关键字中的参数指向基类中需要调用的构造函数。当base关键字不带参数时,将指向基类中无参构造函数,因此基类中无参构造函数除可隐式调用外,也可通过不带参数的base关键字显式调用。
参考文献
[1]侯春英,任华.C#程序设计项目教程[M].北京:航空工业出版社,2017:12.
[2]韩祥波.面向对象程序设计中构造、析构函数的教学探讨[J].电脑知识与技术,2019(12):15-16.
[3]姜静思.分析子类调用父类构造函数[J].科技展望,2015(8):23-25.
[4]胡明珏.面向C#的函数调用路径生成[J].计算机仿真,2016(9):29-30.
[5]王帅.关于C++构造函数的几点探究[J].电脑编程技巧与维护,2013(10):25-26.
关注SCI论文创作发表,寻求SCI论文修改润色、SCI论文代发表等服务支撑,请锁定SCI论文网!
文章出自SCI论文网转载请注明出处:https://www.lunwensci.com/jisuanjilunwen/36826.html