当你定义一个类,你实际上定义的是一个数据类型的蓝图。实际上你并没有定义任何数据,但是它定义了类的名字意味着什么。也就是说,一个类的对象由一些可以在该类上进行的操作构成。对象是类的实例。构成类的方法和变量被称为类的成员。

定义一个类

一个类定义以关键字 class 开始,其后跟的是类的名称;类的主体部分体由一对花括号括起来。以下是一个类定义的一般形式:

  1. class class_name
  2. {
  3. // 成员变量
  4. variable1;
  5. variable2;
  6. ...
  7. variableN;
  8. // 成员变量
  9. method1(parameter_list)
  10. {
  11. // 方法主体
  12. }
  13. method2(parameter_list)
  14. {
  15. // 方法主体
  16. }
  17. ...
  18. methodN(parameter_list)
  19. {
  20. // 方法主体
  21. }
  22. }

笔记:

  • 访问说明符的访问成员的规则与类本身的访问规则相同。如果没有说明,则默认访问的类的类型为 internal 。对成员的默认访问类型是 private

  • 数据类型指定了变量的类型,如果有返回值的话,返回指定方法的数据类型。

  • 访问类的成员,可以使用 “.” 点运算符。

  • 点运算符连接的成员的名字和对象的名称。

下面的例子说明了到目前为止对于概念的讨论:

  1. using System;
  2. namespace BoxApplication
  3. {
  4. class Box
  5. {
  6. public double length; // box 的长度
  7. public double breadth; // box 的宽度
  8. public double height; // box 的高度
  9. }
  10. class Boxtester
  11. {
  12. static void Main(string[] args)
  13. {
  14. Box Box1 = new Box(); // 声明 box1 为 box 类型
  15. Box Box2 = new Box(); // 声明 box2 为 box 类型
  16. double volume = 0.0; // 在这里存放 box 的体积
  17. // box 1 详细数据
  18. Box1.height = 5.0;
  19. Box1.length = 6.0;
  20. Box1.breadth = 7.0;
  21. // box 2 详细数据
  22. Box2.height = 10.0;
  23. Box2.length = 12.0;
  24. Box2.breadth = 13.0;
  25. // box 1 的体积
  26. volume = Box1.height * Box1.length * Box1.breadth;
  27. Console.WriteLine("Volume of Box1 : {0}", volume);
  28. // box 2 的体积
  29. volume = Box2.height * Box2.length * Box2.breadth;
  30. Console.WriteLine("Volume of Box2 : {0}", volume);
  31. Console.ReadKey();
  32. }
  33. }
  34. }

编译执行上述代码,得到如下结果:

  1. Volume of Box1 : 210
  2. Volume of Box2 : 1560

成员函数和封装

一个类的成员函数有其自己定义的或其原型写在类体中。它可以操作该类的任何成员对象,并且可以访问一个类的所有成员。

成员变量是一个对象的属性(从设计的角度来看),他们都是私有(private)的以便实施封装。这些变量只能被 public 成员函数访问。

让我们把上述那些概念来 set 和 get 一个类中不同的类成员的值:

  1. using System;
  2. namespace BoxApplication
  3. {
  4. class Box
  5. {
  6. private double length; // box 的长度
  7. private double breadth; // box 的宽度
  8. private double height; // box 的高度
  9. public void setLength( double len )
  10. {
  11. length = len;
  12. }
  13. public void setBreadth( double bre )
  14. {
  15. breadth = bre;
  16. }
  17. public void setHeight( double hei )
  18. {
  19. height = hei;
  20. }
  21. public double getVolume()
  22. {
  23. return length * breadth * height;
  24. }
  25. }
  26. class Boxtester
  27. {
  28. static void Main(string[] args)
  29. {
  30. Box Box1 = new Box(); // 将 Box1 声明为 Box 类型
  31. Box Box2 = new Box();
  32. double volume;
  33. // 将 Box2 声明为 Box 类型
  34. // box 1 详细数据
  35. Box1.setLength(6.0);
  36. Box1.setBreadth(7.0);
  37. Box1.setHeight(5.0);
  38. // box 2 详细数据
  39. Box2.setLength(12.0);
  40. Box2.setBreadth(13.0);
  41. Box2.setHeight(10.0);
  42. // box 1 的体积
  43. volume = Box1.getVolume();
  44. Console.WriteLine("Volume of Box1 : {0}" ,volume);
  45. // box 2 的体积
  46. volume = Box2.getVolume();
  47. Console.WriteLine("Volume of Box2 : {0}", volume);
  48. Console.ReadKey();
  49. }
  50. }
  51. }

编译执行上述代码,得到如下结果:

  1. Volume of Box1 : 210
  2. Volume of Box2 : 1560

C# 构造函数

一个类的构造函数(constructor)是类的一种特殊的成员函数,当我们创建一个类的新的对象时执行该函数。

构造函数与类具有相同的名称,但它没有任何返回类型。下面的例子说明了构造函数的概念:

  1. using System;
  2. namespace LineApplication
  3. {
  4. class Line
  5. {
  6. private double length; // 线段长度
  7. public Line()
  8. {
  9. Console.WriteLine("Object is being created");
  10. }
  11. public void setLength( double len )
  12. {
  13. length = len;
  14. }
  15. public double getLength()
  16. {
  17. return length;
  18. }
  19. static void Main(string[] args)
  20. {
  21. Line line = new Line();
  22. // 设置线段长度
  23. line.setLength(6.0);
  24. Console.WriteLine("Length of line : {0}", line.getLength());
  25. Console.ReadKey();
  26. }
  27. }
  28. }

编译执行上述代码,得到如下结果:

  1. Object is being created
  2. Length of line : 6

默认构造函数(default constructor)没有任何的参数,但是如果你需要,构造函数是可以有参数的。这种构造函数被称为参数化的构造函数(parameterized constructors)。这种技术有助于你在一个对象被创建时指定它的初始值,如下述示例:

  1. using System;
  2. namespace LineApplication
  3. {
  4. class Line
  5. {
  6. private double length; // 线段长度
  7. public Line(double len) //参数化构造函数
  8. {
  9. Console.WriteLine("Object is being created, length = {0}", len);
  10. length = len;
  11. }
  12. public void setLength( double len )
  13. {
  14. length = len;
  15. }
  16. public double getLength()
  17. {
  18. return length;
  19. }
  20. static void Main(string[] args)
  21. {
  22. Line line = new Line(10.0);
  23. Console.WriteLine("Length of line : {0}", line.getLength());
  24. // 设置线段长度
  25. line.setLength(6.0);
  26. Console.WriteLine("Length of line : {0}", line.getLength());
  27. Console.ReadKey();
  28. }
  29. }
  30. }

编译执行上述代码,得到如下结果:

  1. Object is being created
  2. Length of line : 6
  3. Object is being deleted

C# 析构函数

析构函数(destructor)是类的一种特殊的成员函数,当类的对象在超出作用域时被执行的一种成员函数。一个析构函数的名称是在其类名称前加上一个前缀字符(~),它既不能返回一个值,也不能带有任何参数。

析构函数对退出程序前释放内存资源时非常有用。析构函数不可以被继承或重载。

下面的示例解释了析构函数的概念:

  1. using System;
  2. namespace LineApplication
  3. {
  4. class Line
  5. {
  6. private double length; // 线段长度
  7. public Line() // 构造函数
  8. {
  9. Console.WriteLine("Object is being created");
  10. }
  11. ~Line() //析构函数
  12. {
  13. Console.WriteLine("Object is being deleted");
  14. }
  15. public void setLength( double len )
  16. {
  17. length = len;
  18. }
  19. public double getLength()
  20. {
  21. return length;
  22. }
  23. static void Main(string[] args)
  24. {
  25. Line line = new Line();
  26. // 设置线段长度
  27. line.setLength(6.0);
  28. Console.WriteLine("Length of line : {0}", line.getLength());
  29. }
  30. }
  31. }

编译执行上述代码,得到如下结果:

  1. Object is being created
  2. Length of line : 6
  3. Object is being deleted

C# 类的静态成员

我们可以使用 static 关键字将类成员定义为静态的。当我们声明一个类的静态成员时,意味着无论有多少类的对象被创建,只有一个副本的静态成员。

关键字 static 意味着一个类的成员只有一个实例存在。静态变量被用于定义常数,因为他们的值可以通过调用不创建实例的类而被检索出来。静态变量可以在成员函数或者类的定义以外的地方初始化。你也可以在类的定义中初始化静态变量。

下面的示例论证了静态变量(static variables)的使用:

  1. using System;
  2. namespace StaticVarApplication
  3. {
  4. class StaticVar
  5. {
  6. public static int num;
  7. public void count()
  8. {
  9. num++;
  10. }
  11. public int getNum()
  12. {
  13. return num;
  14. }
  15. }
  16. class StaticTester
  17. {
  18. static void Main(string[] args)
  19. {
  20. StaticVar s1 = new StaticVar();
  21. StaticVar s2 = new StaticVar();
  22. s1.count();
  23. s1.count();
  24. s1.count();
  25. s2.count();
  26. s2.count();
  27. s2.count();
  28. Console.WriteLine("Variable num for s1: {0}", s1.getNum());
  29. Console.WriteLine("Variable num for s2: {0}", s2.getNum());
  30. Console.ReadKey();
  31. }
  32. }
  33. }

编译执行上述代码,得到如下结果:

  1. Variable num for s1: 6
  2. Variable num for s2: 6

你也可以声明 static成员函数。此类函数只能访问静态变量。静态函数的存在甚至先于创建对象。下面的示例论证了静态函数(static functions)的用法:

  1. using System;
  2. namespace StaticVarApplication
  3. {
  4. class StaticVar
  5. {
  6. public static int num;
  7. public void count()
  8. {
  9. num++;
  10. }
  11. public static int getNum()
  12. {
  13. return num;
  14. }
  15. }
  16. class StaticTester
  17. {
  18. static void Main(string[] args)
  19. {
  20. StaticVar s = new StaticVar();
  21. s.count();
  22. s.count();
  23. s.count();
  24. Console.WriteLine("Variable num: {0}", StaticVar.getNum());
  25. Console.ReadKey();
  26. }
  27. }
  28. }

编译执行上述代码,得到如下结果:

  1. Variable num: 3