详解c# 类的构造方法
一、构造方法
类的构造方法是类的成员方法的一种,它的作用是对类中的成员进行初始化操作。类的构造方法分为:
1.静态构造方法
2.实例构造方法
1.静态构造方法
类的静态构造方法是类的成员方法的一种,它的作用是对类中的静态成员进行初始化操作。下面请看代码实例:
usingSystem; namespaceLycheeTest{ classTest{ //定义一个静态成员变量 privatestaticinta; //定义静态构造函数 staticTest(){ //初始化静态成员变量 a=11; } publicvoidShow(){ Console.WriteLine("静态字段a的值是:{0}",a); } } classProgram{ staticvoidMain(string[]args){ Testt=newTest(); t.Show(); Console.ReadKey(); } } }
首先,上面这段代码定义了两个类。第3行代码定义了类Test。定义类的时候,类的访问权限修饰符有两个,一个是public,另一个是internal。当不写任何访问修饰符的时候,类的访问权限默认是internal。这个访问权限的意义是,这个类只能被本程序集访问,不能被本程序集以外的类访问。如果这个类是属于类库的,那么它必须是public的,否则调用它的程序集就不能访问它。第5行代码定义了一个静态字段成员,第7行代码就是静态构造方法。可以看到,静态构造方法的特点是,以static关键字说明这个方法是静态的,方法名称要和类名完全相同,这里要注意大小写。静态构造方法不能含有参数,静态构造方法不能有返回值。在静态构造方法体内可以做初始化静态成员的操作。第11行代码定义了一个实例方法,它的作用是输出静态字段的值。在第16行的类Program中的Main(注意:在java中是main)方法中调用了这个类,第18行创建了这个类的一个实例,第19行调用了类的实例方法。
从上面的代码中可以看到,并没有显式调用类的静态构造方法。
下面请看以上代码的执行结果:
静态字段a的值是:11
可以看到,静态构造方法确实是被执行了。那么上例就是静态构造方法的执行条件之一,在类的实例被创建时,类的静态构造方法将被自动调用。
静态构造方法的调用次序是在静态字段的初始值设定项之后。
也就是第一步是静态字段的默认值设置,第二步是执行静态字段的初始值设定项,第三步就是调用类的静态构造方法。
下面将前面的代码实例修改一下,代码如下:
usingSystem; namespaceLycheeTest{ classTest{ privatestaticinta; staticTest(){ a++; } publicvoidShow(){ Console.WriteLine("静态字段a的值是:{0}",a); 14 } } classProgram{ staticvoidMain(string[]args){ Testt=newTest(); t.Show(); Testt1=newTest(); t.Show(); Console.ReadKey(); } } }
这段代码将静态构造方法做了修改,在方法体内将静态字段a进行自增操作。然后在代码的第17行又创建了一个类的实例,然后再次调用类的实例方法。
下面看执行结果:
静态字段a的值是:1 静态字段a的值是:1
可以看到,静态字段的值并没有增加。这就是静态构造方法执行的特点,它只执行了一次。当程序集运行的时候,将会创建一个应用程序域,在一个应用程序域中,类的静态构造方法仅仅执行一次。
下面再对代码实例进行修改如下:
usingSystem; namespaceLycheeTest{ classTest{ publicstaticinta; staticTest(){ Console.WriteLine("类的静态构造方法开始执行"); a++; } publicvoidShow(){ Console.WriteLine("静态字段a的值是:{0}",a); } } classProgram{ staticvoidMain(string[]args){ Console.WriteLine("静态字段a的值是:{0}",Test.a); Console.WriteLine("静态字段a的值是:{0}",Test.a); Console.ReadKey(); } } }
这段代码在类的静态构造方法中打印输出了一行标记,类的静态字段的访问权限也修改为public,这让它可以在类外被调用。在Main方法中两次打印输出了静态字段的值,注意在类外调用类的静态字段需要使用类名进行引用。
下面是代码的执行结果:
类的静态构造方法开始执行 静态字段a的值是:1 静态字段a的值是:1
本段代码并没有创建类的实例。在引用类的静态成员之前,类的静态构造方法将被调用。这个被调用的类的静态成员包括静态字段和静态方法。这就是类的静态构造方法调用的第二个条件。
下面再对代码实例进行修改如下:
usingSystem; namespaceLycheeTest{ classProgram{ privatestaticinta; staticProgram(){ Console.WriteLine("类的静态构造方法被调用"); a=11; } staticvoidMain(string[]args){ Console.WriteLine("Main方法被调用"); Console.WriteLine("静态字段a的值是:{0}",a); Console.ReadKey(); } } }
这段代码在包含Main方法的类中定义了静态字段和静态构造方法。因为Main方法也是一个静态方法,类的静态构造方法被调用而且它是类的入口点方法,那么它和类的静态构造方法之间是谁先调用呢?下面首先来看代码的执行结果:
类的静态构造方法被调用 Main方法被调用 静态字段a的值是:11
通过代码的执行结果可以看到,因为类的入口点方法仍然是一个静态方法,那么在任何静态成员被调用之前,静态构造方法都首先被调用。所以,可以得出如下结论,类的静态构造方法先于类的Main方法被调用。
那么类的静态构造方法能否被显式调用呢?下面看代码实例:
usingSystem; namespaceLycheeTest{ classProgram{ privatestaticinta; staticProgram(){ Console.WriteLine("类的静态构造方法被调用"); a=11; } staticvoidMain(string[]args){ Program(); Console.ReadKey(); } } }
在这段代码中的第10行显式调用了类的静态构造方法,这时编译器会报错。
2.实例构造函数
类的实例构造方法是类的成员方法的一种,它的作用是对类的实例成员进行初始化操作。实例构造方法可以实现重载,在创建类的实例时,可以显式的指定不同的参数来调用重载的不同的实例构造方法。下面请看代码实例:
usingSystem; namespaceLycheeTest{ classProgram{ privatestaticinta; privateintb=12; privatestringc="HelloWorld"; staticProgram(){ Console.WriteLine("类的静态构造方法被调用"); a=11; } publicProgram(inta,strings){ Console.WriteLine("带二个参数的构造方法被调用"); this.b=a; this.c=s; } publicProgram(inta):this(a,"通过this关键字调用构造方法"){ Console.WriteLine("带一个参数的构造方法被调用"); } publicvoidShow(){ Console.WriteLine("静态字段a的值是:{0}",a); Console.WriteLine("实例字段b的值是:{0}",b); Console.WriteLine("实例字段c的值是:{0}",c); } staticvoidMain(string[]args){ Programp1=newProgram(33,"这是创建的实例P1"); Programp2=newProgram(34); p1.Show(); p2.Show(); Console.ReadKey(); } }
这段代码的第4行、第5行和第6行分别定义了三个字段成员,第4行是静态字段,第5行和第6行代码都有初始值设定项。代码的第8行就是一个实例构造方法的定义,实例构造方法也是以类名作为方法名,它没有返回值,在方法名前面是访问权限修饰符,可以使用的访问权限修饰符包括public、private和protected。其中的protected意味着构造方法只能在此类内部访问。实例构造方法可以带参数。第12行代码的实例构造方法使用两个传入的参数对实例字段进行了赋值。第17行代码定义了带一个参数的实例构造方法,它和前一个实例构造方法形成了重载。实例构造方法可以通过this关键字调用其他的实例构造方法,方法就是在参数列表的后面使用冒号然后接this关键字,然后再跟参数列表,这个参数列表要匹配另一个重载的实例构造方法。第17行的构造方法只有一个参数,它将这个参数通过this关键字传递给了另一个构造方法,在用this调用另一个构造方法的时候,为其同时传入了一个字符串参数。第24行的实例方法打印类的字段成员的值。在Main方法中,第26行代码和第27行代码分别定义了两个实例,它们使用new关键字调用了不同的实例构造方法。第28行和第29行分别调用实例方法打印类的静态字段和实例的两个字段成员的值。
下面先来看代码的执行结果:
类的静态构造方法被调用带二个参数的构造方法被调用带二个参数的构造方法被调用带一个参数的构造方法被调用 静态字段a的值是:11 实例字段b的值是:33 实例字段c的值是:这是创建的实例P1静态字段a的值是:11 实例字段b的值是:34 实例字段c的值是:通过this关键字调用构造方法
现在用执行结果来介绍实例构造方法的执行过程,当第26行代码创建类的实例时,类的静态字段首先被设置成默认值,因为没有字段的初始值设定项,所以接着就执行类的静态构造方法。这时静态字段a被设置成11。因为第26行代码使用new调用了带有两个参数的实例构造方法,所以首先实例字段b被设置为0,实例字段c被设置为null。然后执行字段的初始值设定项,b被赋值为12,c被赋值为“HelloWorld”。接下来执行实例构造方法体中的第一个语句,“带二个参数的构造方法被调用”这个字符串被打印。接下来实例p1的字段b被设置为传入的参数33,注意构造方法的形参a在这里覆盖了类的静态字段a。也就是说,这时起作用的是实例构造方法的局部变量a。然后实例字段c被设置为字符串"这是创建的实例P1"。第27行代码使用new关键字调用了带一个参数的实例构造方法,在调用时,首先属于p2的实例字段b被设置为0,实例字段c被设置为null。然后执行字段的初始值设定项,b被赋值为12,c被赋值为“HelloWorld”。接下来执行的是this引用的带两个参数的实例构造方法,"带二个参数的构造方法被调用"这个字符串被打印。然后b被设置为34,c被设置为"通过this关键字调用构造方法"。最后,代码控制又返回来执行带一个参数的实例构造方法体中的打印语句,"带一个参数的构造方法被调用"这个字符串被打印。至此,实例构造方法的执行完毕。接下来的代码打印静态字段的值,可以看到两个实例打印出来的静态字段值是一样的,但是它们的实例字段的值各不相同。
可选参数和命名参数也可以用于实例构造方法,下面看代码实例:
usingSystem; namespaceLycheeTest{ classProgram{ privateintb; privatestringc; publicProgram(inta=12,strings=""){ this.b=a; this.c=s; } publicvoidShow(){ Console.WriteLine("实例字段b的值是:{0}",b); Console.WriteLine("实例字段c的值是:{0}",c); } staticvoidMain(string[]args){ Programp1=newProgram();//构造方法的两个参数都采用默认值 Programp2=newProgram(34);//构造方法的string类型参数采用默认值 Programp3=newProgram(23,"HelloWorld");//构造方法的两个参数采用传入参数 Programp4=newProgram(s:"今天的天气真好");//采用命名参数,另一个参数a采用默认值 p1.Show(); p2.Show(); p3.Show(); p4.Show(); Console.ReadKey(); } } }
代码的第6行定义了一个带有可选参数和命名参数的构造方法,然后第15创建了一个类的实例,在构造方法中没有传入任何参数,这时,构造方法的两个参数都采用默认值。第16行代码为构造方法传入了一个int类型的参数,这时,另一个string类型的参数采用默认值。第17行代码传入了两个参数,构造方法的两个参数都使用了这两个传入的参数。第18行代码使用了命名参数指定传入的参数是string类型的参数,并将它传递给形参s。这时另一个int类型的参数采用默认值。第19行到第23行代码打印类的实例字段的值。这段代码的执行结果如下:
实例字段b的值是:12 实例字段c的值是: 实例字段b的值是:34 实例字段c的值是: 实例字段b的值是:23 实例字段c的值是:HelloWorld实例字段b的值是:12 实例字段c的值是:今天的天气真好
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持毛票票!