C# 类(Class)

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

类的定义

类的定义是以关键字 class 开始,后跟类的名称。类的主体,包含在一对花括号内。下面是类定义的一般形式:

  1. <access specifier> class class_name
  2. {
  3. // member variables
  4. <access specifier> <data type> variable1;
  5. <access specifier> <data type> variable2;
  6. ...
  7. <access specifier> <data type> variableN;
  8. // member methods
  9. <access specifier> <return type> method1(parameter_list)
  10. {
  11. // method body
  12. }
  13. <access specifier> <return type> method2(parameter_list)
  14. {
  15. // method body
  16. }
  17. ...
  18. <access specifier> <return type> methodN(parameter_list)
  19. {
  20. // method body
  21. }
  22. }

  

请注意:

  • 访问标识符 <access specifier> 指定了对类及其成员的访问规则。如果没有指定,则使用默认的访问标识符。类的默认访问标识符是 internal,成员的默认访问标识符是 private
  • 数据类型 <data type> 指定了变量的类型,返回类型 <return type> 指定了返回的方法返回的数据类型。
  • 如果要访问类的成员,你要使用点(.)运算符。
  • 点运算符链接了对象的名称和成员的名称。

下面的实例说明了目前为止所讨论的概念:

  1. using System;
  2. namespace BoxApplication
  3. {
  4. class Box
  5. {
  6. public double length; // 长度
  7. public double breadth; // 宽度
  8. public double height; // 高度
  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; // 体积
  17.  
  18. // Box1 详述
  19. Box1.height = 5.0;
  20. Box1.length = 6.0;
  21. Box1.breadth = 7.0;
  22.  
  23. // Box2 详述
  24. Box2.height = 10.0;
  25. Box2.length = 12.0;
  26. Box2.breadth = 13.0;
  27.  
  28. // Box1 的体积
  29. volume = Box1.height * Box1.length * Box1.breadth;
  30. Console.WriteLine("Box1 的体积: {0}", volume);
  31.  
  32. // Box2 的体积
  33. volume = Box2.height * Box2.length * Box2.breadth;
  34. Console.WriteLine("Box2 的体积: {0}", volume);
  35. Console.ReadKey();
  36. }
  37. }
  38. }

成员函数和封装

类的成员函数是一个在类定义中有它的定义或原型的函数,就像其他变量一样。作为类的一个成员,它能在类的任何对象上操作,且能访问该对象的类的所有成员。

成员变量是对象的属性(从设计角度),且它们保持私有来实现封装。这些变量只能使用公共成员函数来访问。

让我们使用上面的概念来设置和获取一个类中不同的类成员的值:

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

C# 中的构造函数

类的 构造函数 是类的一个特殊的成员函数,当创建类的新对象时执行。

构造函数的名称与类的名称完全相同,它没有任何返回类型。

下面的实例说明了构造函数的概念:

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

默认的构造函数没有任何参数。但是如果你需要一个带有参数的构造函数可以有参数,这种构造函数叫做参数化构造函数。这种技术可以帮助你在创建对象的同时给对象赋初始值,具体请看下面实例:

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

C# 中的析构函数

类的 析构函数 是类的一个特殊的成员函数,当类的对象超出范围时执行。

析构函数的名称是在类的名称前加上一个波浪形(~)作为前缀,它不返回值,也不带任何参数。

析构函数用于在结束程序(比如关闭文件、释放内存等)之前释放资源。析构函数不能继承或重载。

下面的实例说明了析构函数的概念:

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

C# 类的静态成员

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

关键字 static 意味着类中只有一个该成员的实例。静态变量用于定义常量,因为它们的值可以通过直接调用类而不需要创建类的实例来获取。静态变量可在成员函数或类的定义外部进行初始化。你也可以在类的定义内部初始化静态变量。

下面的实例演示了静态变量的用法:

  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("s1 的变量 num: {0}", s1.getNum());
  29. Console.WriteLine("s2 的变量 num: {0}", s2.getNum());
  30. Console.ReadKey();
  31. }
  32. }
  33. }

你也可以把一个成员函数声明为 static。这样的函数只能访问静态变量。静态函数在对象被创建之前就已经存在。下面的实例演示了静态函数的用法:

  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("变量 num: {0}", StaticVar.getNum());
  25. Console.ReadKey();
  26. }
  27. }
  28. }

将类成员函数声明为public static无需实例化即可调用类成员函数

  1. using System;
  2.  
  3. namespace ConsoleApp
  4. {
  5. class Program
  6. {
  7. static void Main(string[] args)
  8. {
  9. int num = AddClass.Add(2, 3); //编译通过
  10. Console.WriteLine(num);
  11. }
  12. }
  13.  
  14. class AddClass
  15. {
  16. public static int Add(int x,int y)
  17. {
  18. return x + y;
  19. }
  20. }
  21. }

反之,如果不声明为static,即使和Main方法从属于同一个类,也必须经过实例化

  1. using System;
  2.  
  3. namespace ConsoleApp
  4. {
  5. class Program
  6. {
  7. static void Main(string[] args)
  8. {
  9. int num = Add(2, 3); //编译错误,即使改为Program.Add(2, 3);也无法通过编译
  10. Console.WriteLine(num);
  11. }
  12.  
  13. public int Add(int x, int y)
  14. {
  15. return x + y;
  16. }
  17. }
  18. }
  19. using System;
  20.  
  21. namespace ConsoleApp
  22. {
  23. class Program
  24. {
  25. static void Main(string[] args)
  26. {
  27. Program self = new Program();
  28. int num = self.Add(2, 3); //编译通过
  29. Console.WriteLine(num);
  30. }
  31.  
  32. public int Add(int x, int y)
  33. {
  34. return x + y;
  35. }
  36. }
  37. }

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

关键字 static 意味着类中只有一个该成员的实例。静态变量用于定义常量,因为它们的值可以通过直接调用类而不需要创建类的实例来获取。静态变量可在成员函数或类的定义外部进行初始化。你也可以在类的定义内部初始化静态变量。

将类成员函数声明为public static无需实例化即可调用类成员函数

反之,如果不声明为static,即使和Main方法从属于同一个类,也必须经过实例化

倘若在类的声明中没有显式地提供实例构造函数,在这种情况下编译器会提供一个隐式的默认构造函数,它具有以下特点:

①不带参数;

②方法体为空。

但是如果你声明了任何构造函数,那么编译器就不会把该类定义为默认构造函数。

例如:

  1. class Class2
  2. {
  3. public Class2(int Value) {...} //构造函数0
  4. public Class2(String Value) {...} //构造函数1
  5. }
  6.  
  7. class Program
  8. {
  9. static void Main()
  10. {
  11. Class2 a = new Class2(); //错误!没有无参数的构造函数
  12. ...
  13. }
  14. }

在以上的代码中至少有一个显式定义的构造函数,编译器不会创建任何额外的构造函数,在 Main() 中如果试图用不带参数的构造函数创建新的实例,因为没有无参数的构造函数,所以编译器就会产生一条错误信息。

类Class的更多相关文章

  1. Java类的继承与多态特性-入门笔记

    相信对于继承和多态的概念性我就不在怎么解释啦!不管你是.Net还是Java面向对象编程都是比不缺少一堂课~~Net如此Java亦也有同样的思想成分包含其中. 继承,多态,封装是Java面向对象的3大特 ...

  2. C++ 可配置的类工厂

    项目中常用到工厂模式,工厂模式可以把创建对象的具体细节封装到Create函数中,减少重复代码,增强可读和可维护性.传统的工厂实现如下: class Widget { public: virtual i ...

  3. Android请求网络共通类——Hi_博客 Android App 开发笔记

    今天 ,来分享一下 ,一个博客App的开发过程,以前也没开发过这种类型App 的经验,求大神们轻点喷. 首先我们要创建一个Andriod 项目 因为要从网络请求数据所以我们先来一个请求网络的共通类. ...

  4. ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库

    在这一章中,我们将直接进入项目,并且为产品和分类添加一些基本的模型类.我们将在Entity Framework的代码优先模式下,利用这些模型类创建一个数据库.我们还将学习如何在代码中创建数据库上下文类 ...

  5. ASP.NET Core 折腾笔记二:自己写个完整的Cache缓存类来支持.NET Core

    背景: 1:.NET Core 已经没System.Web,也木有了HttpRuntime.Cache,因此,该空间下Cache也木有了. 2:.NET Core 有新的Memory Cache提供, ...

  6. .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类

    .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类 0x00 为什么要引入扩展方法 有的中间件功能比较简单,有的则比较复杂,并且依赖其它组件.除 ...

  7. Java基础Map接口+Collections工具类

    1.Map中我们主要讲两个接口 HashMap  与   LinkedHashMap (1)其中LinkedHashMap是有序的  怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...

  8. PHP-解析验证码类--学习笔记

    1.开始 在 网上看到使用PHP写的ValidateCode生成验证码码类,感觉不错,特拿来分析学习一下. 2.类图 3.验证码类部分代码 3.1  定义变量 //随机因子 private $char ...

  9. C# 多种方式发送邮件(附帮助类)

    因项目业务需要,需要做一个发送邮件功能,查了下资料,整了整,汇总如下,亲测可用- QQ邮箱发送邮件 #region 发送邮箱 try { MailMessage mail = new MailMess ...

  10. .NET平台开源项目速览(18)C#平台JSON实体类生成器JSON C# Class Generator

    去年,我在一篇文章用原始方法解析复杂字符串,json一定要用JsonMapper么?中介绍了简单的JSON解析的问题,那种方法在当时的环境是非常方便的,因为不需要生成实体类,结构很容易解析.但随着业务 ...

随机推荐

  1. QT 连接SQLIte数据库

    1.新建一个qt应用程序 2.在.pro文件中添加 sql     (下图,可以查看使用方法) 添加结构查看: 3.开始连接数据库 4.运行结果查看: 5.查看数据库文件: 6.使用可视化工具创建一个 ...

  2. Redis Stack(生产适配-仅提供 Redis Stack 服务器) (6.2.4-v2版本)

    一.使用docker安装(生产适配-仅提供 Redis Stack 服务端) (6.2.4-v2版本) 简介 安装命令根据实际部署情况调整 版本地址:官方镜像主页 | 发布版Tags 指定版本命令-推 ...

  3. hostPath类型的卷挂载

    卷类型之hostPath hostPath类型的卷可以把宿主机节点上的文件或文件夹挂载到pod中 先来看看hostPath类型的卷如何配置: apiVersion: v1 kind: Pod meta ...

  4. pgsql计算占比

    SELECT len/sum(len)over(partition by road_id) param from road_jcpd_section

  5. 【26期】如何判断一个对象是否存活?(或者GC对象的判定方法)?

    这个问题,面试被问到的概率还是很大的.以下关于 如何判断一个对象是否存活 的回答,完全参照<深入理解Java虚拟机>一书,有需要的可以看书学习.以下是题目解析 判断对象是否存活的算法包括: ...

  6. shell脚本:报错syntax error near unexpected token `$'\r''解决方法

    之前的shell脚本是在服务器上编写的,后来又已复制的方式存在在了电脑上,以txt文件的形式存放的.于是复制到了编辑工具中,进行了相应项的修改.修改完毕后,拿到服务器上测试,结果执行sh XXX.sh ...

  7. Linux-curl下载报错解决方法

    报错提示: curl: (92) HTTP/2 stream 1 was not closed cleanly before end of the underlying stream ==> E ...

  8. 设计模式,mvc,mvp,mvvm

    mvc model模型-视图view-控制器controller 视图可以直接访问模型,所以视图里面包括模型信息,mvc关注的是模型不变,所以在mvc中,模型不依赖视图,但是view是依赖model的 ...

  9. 在Github上搭建个人主页

    最近试着在github上搭建个人主页,没用github给的模板,用的是自己在网上找到那种类似个人主页的模板,到时候直接上传到仓库里就行了 首先先创建仓库,点击右上角的加号,选择New reposito ...

  10. ajv参数验证

    1.验证枚举类型 var schema = { "properties": { "data": { "type": "object ...