当定义一个类之后就可以通过new运算符将其实例化,产生一个对象。weineng规范、安全地使用这个对象,C#提供了实现对象进行初始化的方法,这就是构造函数。
一般的构造函数总是public类型的。如果是private类型的,表明类不能被外部类实例化。
构造函数名必须与这个类同名,不声明返回类型,并且没有任何返回值。它返回值类型为void的函数不同。构造函数可以没有参数也可以有一个或者多个参数。这表明构造函数在类的申明中可以有函数名相同,但参数类型不同或者参数个数不同的多种形式,这就是构造函数重载。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 public class Time 7 { 8 public int hour, minute, second; 9 public Time() 10 { 11 hour = minute = second = 0; 12 } 13 public Time(int h) 14 { 15 hour = h; 16 minute = second = 0; 17 } 18 public Time(int h, int m) 19 { 20 hour = h; 21 minute = m; 22 second = 0; 23 } 24 public Time(int h, int m, int s) 25 { 26 hour = h; 27 minute = m; 28 second = s; 29 } 30 } 31 class Program 32 { 33 static void Main(string[] args) 34 { 35 Time t1, t2, t3, t4; 36 t1 = new Time(); 37 t2 = new Time (8); 38 t3 = new Time (8,30); 39 t4 = new Time (8,30,45); 40 Console.WriteLine( "t1"); 41 Console.WriteLine("t2.hour={0} ", t2.hour); 42 Console.WriteLine("t3.hour={0} ,t3.minute={1} ", t3.hour, t3.minute); 43 Console.WriteLine("t4.hour={0} ,t4.minute={1} ,t4.second={2} ", t4.hour, t4.minute,t4.second); 44 Console.Read(); 45 } 46 }
构造函数初始化:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Constructor_Point 7 { 8 class Point 9 { 10 public double x, y; 11 public Point() 12 { 13 x = 0; 14 y = 0; 15 } 16 public Point(double x, double y) 17 { 18 this.x = x; 19 this.y = y; 20 21 } 22 } 23 class Program 24 { 25 static void Main(string[] args) 26 { 27 Point a; 28 a = new Point(); 29 Point b; 30 b = new Point(3, 4); 31 Console.WriteLine("a.x = {0} , a.y = {1}", a.x, a.y); 32 Console.WriteLine("b.x = {0} , b.y = {1}", b.x, b.y); 33 Console.Read(); 34 } 35 } 36 }
派生类:
当创建派生类的对象时,就会展开一个链式的构造函数调用,在这个过程中,派生类构造函数在执行它自己的函数体之前,首先显示或者隐式地调用基类构造函数。类似的如果这个基类也是从另一个类派生而来的,那么这个基类的构造函数在执行之前也会先调用它的基类的构造函数之后,在执行成员对象的构造函数,最后执行派生类的构造函数,默认情况下执行基类的无参构造函数,如果要执行基类的有参构造函数,则必须在派生类构造函数的基类列表中指出。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 class Point 7 { 8 private int x, y; 9 public Point() 10 { 11 x = 0; 12 y = 0; 13 Console.WriteLine("Point() constructor:{0}", this); 14 } 15 public Point(int x, int y) 16 { 17 this.x = x; 18 this.y = y; 19 Console.WriteLine("Point(x,y) constructor:{0}", this); 20 } 21 } 22 class Circle : Point 23 { 24 private double radius; 25 public Circle() 26 { 27 Console.WriteLine("Circle() constructor:{0}", this); 28 } 29 public Circle(double radius) 30 : base() 31 { 32 this.radius = radius; 33 Console.WriteLine("Circle(radius) constructor:{0}", this); 34 } 35 public Circle(int x, int y, double radius) 36 : base(x, y) 37 { 38 this.radius = radius; 39 Console.WriteLine("Circle(x, y, radius) constructor:{0}", this); 40 } 41 } 42 class Program 43 { 44 static void Main(string[] args) 45 { 46 Point a = new Point(); 47 Circle b = new Circle(3.5); 48 Circle c = new Circle(1, 1, 4.8); 49 Console.Read(); 50 } 51 }
关于构造函数的注意点:
:base([参数列表]) ——表示调用直接基类中的实例构造函数。
:this([参数列表]) ——表示调用该类本身所申明的其他构造函数。
构造函数语句块——既可以对静态字段赋值,也可以对非静态字段进行初始化。但在构造函数体中不要对类的实例进行初始化以外的事情,也不要尝试显示地调用构造函数。
实例构造函数——不能被继承。如果一个类没有声明任何实例构造函数,则系统会自动提供一个默认的实例构造函数。
静态构造函数体:——静态构造函数的目的是对静态字段的初始化,所以他只能对静态数据成员进行初始化,而不能对非静态数据成员进行初始化。
1 class Screen 2 { 3 static int Height; 4 static int Width; 5 int Cur_X, Cur_Y; 6 static Screen() 7 { 8 Height = 768; 9 Width = 1024; 10 }
关于静态构造函数的注意点:
1、静态构造函数是不可继承的,而且不能被直接调用;
2、只有创建类的实例或者引用类的任何静态成员时,才能激活静态构造函数,所以在给定的应用程序域中静态构造函数之多被执行一次。
3、如果类中没有声明静态构造函数,而又包含带有初始设定的静态字段,那么编译器会自动生成一个默认的静态构造函数。
析构函数:
创建一个对象时需要用构造函数初始化数据,与此相对应的释放一个对象时就需要用析构函数。所以析构函数时用于实现析构类实例所需操作的方法。
析构函数不能写返回值,也不能带参数,因此它不能被重载,当然也不能被继承,所以一个类最多只能有一个析构函数,一个类如果没有显示地声明析构函数,则编译器将自动产生一个默认的析构函数。
关于析构函数的几个注意点:
1、析构函数不能由程序显示地调用,而是由系统在释放对象时自动调用。
2、如果对象是一个派生类对象,那么在调用析构函数是也会产生自己的链式反应,首先执行派生类的析构函数,然后执行基类的析构函数,如果这个基类还有自己基类,这个过程就会不断地重复,直到调用Object类的析构函数为止,其执行顺序正好与构造函数相反。