构造函数

来源:互联网 发布:java游戏服务器端开发 编辑:程序博客网 时间:2024/06/12 01:39
 
通用语言运行时CLR要求每个类都有一个构造函数。构造函数是一个有特殊用途的方法,第一次引用时会初始化类或类实例。主要有三类构造函数:实例构造函数(instance)私有构造函数(private,实例构造函数的一种特殊情况)静态构造函数(static)
 
 
 
  •    实例构造函数(instance):
           语法
[attribute] [modifiers] <identifier> ([parameter-list])
[:initializer] { constructor
-body}
构造函数不仅没有返回数据类型,而且还增加了一个intaializer(初始化调用)选项,除此之外,构造函数的语法与一般方法的语法是相同的。不过二者在实现和行为上存在一些区别:
identifier(构造函数名)必须与类相同。
通过initializer(初始化调用),可以在输入constructor-body(构造函数体)之前先行调用代码。它有如下两种形式:
  •    base(argument list)-调用基类
  •    this(argulist list)-掉用这个类的另一个构造函数。
  •   如果类没有构造函数,编译器会提供一个没有参数的构造函数。
调用实例构造函数是创建类实例的一部分。因为类可能包含多个构造函数,所以编译器将根据构造函数签名,选用与调用匹配的构造函数:
Fiber fib1 = new Cotton();
Fiber fib2 = new Cotton(Egyptian);
.NET创建对象的过程是:分配内存空间,然后将内存空间清0,再调用实例构造函数。构造函数要设置对象的状态。类中未显示初始的字段都被设置为0或null,究竟是那个取决于字段的类型。
 
  • 继承构造函数
构造函数不像方法,它是不能继承的。每个类都要定义自己的构造函数,或者使用默认的无参数构造函数。
在执行构造函数的第一行代码之前,每个构造函数必须首先调用基类的第一个构造函数。由于C#会自动生成对基类默认构造函数的调用,所以,程序员通常不用考虑这个问题。不过也有一些例外。考虑下面的代码Apparel定义了一个构造函数:
public class Apparel
{
    
private string color;
    
private decimal price;
    
//constructor
    public Apparel(string c, decimal p, string b)
    {
        color 
= c;
        price 
= p;
    }
}


public class Cost : Apparel
{
    
private string lenght;
    
public Cost(string c, decimal p, string b, string l)
    {
        lenght 
= l;
    }
}
编译这段代码出现: “Apparel”方法没有采用“0”个参数的重载。错误提示,出现这种的原因有两个:第一,由于Apparel有一个显式的构造函数,所以,编译器不会在类中怎家默认的无参数构造函数;第二,在编译派生类构造函数时,编译器加入了对基类默认构造函数的调用。而这个例子中基类没有默认的构造函数。要解决这个问题可以在基类中增加一个无参数的构造函数,也可以在派生类中包含一个对基类显式构造函数的调用。
 
 
使用初始化调用
C#编译器提供了基类初始化调用(initializer),以便继承子类中的构造函数能调用基类的构造函数。如果多个类共享基类构造函数设置的一些公共成员属性,那么这就很有用。下面这个例子为你展示了Shirt如何调用Apparel基类的构造函数。
 
public class Apparel
{
    
private string color;
    
private decimal price;
    
private string brand;
    
public Apparel(String c, decimal p, string b)
    {
        color 
= c;
        price 
= p;
        brand 
= b;
    }
    
public string ItemColor
{
get { return color; }}
}
public class Shirt : Apparel
{
    
private decimal mySleeve;
    
private decimal myColor;
    
public Shirt(string c, decimal p, string b, decimal sleeve, decimal collar): base(c, p, b)
    {
        myColor 
= sleeve;
        mySleeve 
= sleeve;
    }
}

public class TestClass
{
    
static void Main()
    {
        Shirt shritClass 
= new Shirt("white"15.00m"Arrow"32.0m15.3m);
        Console.Write(shritClass.ItemColor);
    }
}
 
为了得到更高效率的代码,可以在一个构造函数中完成字段初始化,而在另一个构造函数中使用this初始化调用前一个构造函数。
public class Point
{
    
public double x, y;

    
public Point()
    {
        
this.x = 0;
        
this.y = 0;
    }

    
public Point(double x, double y)
    {
        
this.x = x;
        
this.y = y;
    }
}
public class TestPoint
{
    
static void Main()
    {
        Point a 
= new Point();
        Point b 
= new Point(34);
    }
}

 

私有构造函数
对类构造函数应用private修饰符时,则禁止外部类创建该类的实例。如果只通过静态方法和字段来提供功能那么就常常使用私有构造函数。
现在出现这样一个问题,要避免实例化,使用私有构造函数好呢,还是使用抽象类好一些?答案在于要理解其二者的区别,首先来考虑继承,虽然抽象类不能实例化,但其真正目的是用来做为基类,以便派生创建自己的实现。使用私有构造函数的类不会被继承,而且也不能被继承。其次私有构造函数只能精致外部类对该类的实例化,却不能禁止在该类内部创建实例。
私有构造函数的特性也可以用于管理对象的创建。虽然私有构造函数不允许外部方法实例这个类,但却允许此类中的公共方法(有时也称工厂方法 foctory method)创建对象。也就是说类可以创建自身的实例、控制外界对它的访问,以及控制创建实例的个数。
 
静态构造函数
静态构造函数(static contructor)也称为类或类型构造函数,它在加载类型之后及在访问任一类型成员之前执行。其主要作用是初始化静态类成员。它的作用只所以有限,原因是它有很所限制,正是这些限制使静态构造函数与类实例构造函数有所区别:
  • 它不能有参数,不能重载,因此,类只能有一个静态构造函数。
  • 它的访问性必须是pirvate,这由C#自动指定。
  • 它不能调用其他的构造函数。
  • 它只能访问静态成员。
虽然静态构造函数没有参数但不要把它与默认的构造函数混淆:默认的基构造函数必须是实例构造函数。下面代码展示了实例构造函数和静态构造函数之间的区别:
class BaseClass
{
    
private static int callconunter;
    
//Static Constructor
    static BaseClass()
    {
        Console.WriteLine(
"Strtic Constructor:" + callconunter);
    }
    
//Instance constructor
    public BaseClass()
    {
        callconunter 
+= 1;
        Console.WriteLine(
"instance constructor:" + callconunter);
    }
}

实例化构造函数:
        BaseClass myclass1 = new BaseClass();
        BaseClass myclass2 
= new BaseClass();
        BaseClass myclass3 
= new BaseClass();
 
输出:
Strtic Constructor:0
instance constructor:1
instance constructor:2
instance constructor:3
 
编译器首先生成代码,将静态字段初始化为0,然后执行静态构造函数代码显示callConuter的初始值。接下来执行基构造函数,计数器值增1,并显示当前值为1.每创建一个新的BaseClass类实例,计数器都增1.注意,不管创建多少个类实例,静态构造函数都只执行一次。
原创粉丝点击