构造函数是在实例化对象时自动调用的函数。构造函数的名字不能随便起,它们必须与所属的类同名。除了名字外,构造函数的另一个特别之处是没有返回值类型,这与返回值类型为void的函数不同。构造函数用于初始化字段的值。在你可以访问一个类的方法、属性或任何其它东西之前,第一条执行的语句是包含有相应类的构造函数。甚至你自己不写一个构造函数,也会有一个缺省构造函数提供给你。如下。
//如果类没有显示的写构造函数,那么在实例化的时候 //实际上系统会给这个类分配如下这样一个由CLR提供的构造函数 class Product { public Product() : base() { } // 由CLR提供 } |
小天:哦,也就是说我们前面写的那些User、Product等类中虽然都没有显示的写构造函数,可实际上每次new的时候,编译器都执行了一个CLR提供的缺省构造函数。
老田:是的。下面我们再来看一种,也是我们写得最多的。实例构造函数
实例构造函数是实现对类中实例进行初始化的方法成员。如:
using System; using System.Text;
namespace _4_5_ProductManagr { public class Product { // 商品名 private string _name; // 价格 private decimal _price; // 颜色 private string _color;
public Product() { //初始化私有字段的值 _name = "天轰穿系列图书"; _price = 300.00M; _color = "花花绿绿"; } } } |
对于上面这个类,只要实例化后(使用new实例化一个对象,以后不再提示),类中的三个变量就都具有值了。如下:
Product pd = new Product(); //这样实例化以后,里面的私有变量就都有值了 |
小天:但这样值就是固定的了,能否在我实例化的时候再自定义不?
老田:可以的,我们将上面的构造函数修改如下:
///<summary> ///初始化商品类 ///</summary> ///<param name="n">商品名</param> ///<param name="p">商品价格</param> ///<param name="c">商品颜色</param> public Product(string n,decimal p,string c) { _name = n; //将传入的参数赋值给私有字段 _price = p; _color = c; } |
对于上面的代码,要实例化就必须给值了,如下
Product pd = new Product("天轰穿系列图书", 23.45M, "蓝色"); |
不过需要提醒的是,只要我们为类写了一个构造函数,那么CLR就不会再帮我们提供了。换句话说,比如类中编写了上面这样一个需要三个参数的构造函数。那么每次实例化这个对象的时候就必须要给三个参数,否则会出错。
小天:为什么我看人家哪些类就是想写几个参数就写几个,想不写就不写,都不会出错?还有构造函数一定要访问修饰符吗?如果给个private有什么效果?
老田:人家那个不会出错时因为使用了重载,方法和构造函数都可以重载,等讲完方法后,统一来讨论。
而你说到访问修饰符的问题,接下来看下另外一种特殊的构造函数:静态构造函数
静态构造函数是实现对一个类进行初始化的方法成员。它一般用于对静态数据的初始化。静态构造函数不能有参数,不能有修饰符而且不能被调用,当类被加载时,类的静态构造函数自动被调用。如:
public class Product { private static int storage; //静态字段 static Product() //静态构造函数不需要访问修饰符 { storage = 1000; } } |
注意静态构造函数只能对静态数据成员(用static修饰过的数据成员)进行初始化,而不能对非静态数据成员进行初始化。但是,非静态构造函数既可以对静态数据成员赋值,也可以对非静态数据成员进行初始化。
如果类仅包含静态成员,你可以创建一个private的构造函数:private TestClass() {…},但是private意味着从类的外面不可能访问该构造函数。所以,它不能被调用,且没有对象可以被该类定义实例化。
本文章为天轰穿原创文章,转载请注明出处及作者