C#之面向对象

一:字符串操作之常用方法

  1. ToUpper()
    将字符转换成大写形式,仅对字母有效。
    返回值是转换后的字符串。
    使用:字符串变量.方法名(); 例如:name.ToUpper();
  2. ToLower()
    将字符转换成小写形式,仅对字母有效。
    返回值是转换后的字符串。
    使用:字符串变量.方法名(); 例如:name.ToUpper();
  3. Equals()
    比较两个字符串是否相同。相同返回真,不相同返回假。
    使用:字符串变量.方法名(要比较的字符串变量); 例如:name.Equals(name2);
  4. Split()
    分割字符串。返回字符串类型的数组。
    使用:字符串变量.方法名(用于分割的字符数组); 例如:name3.Split(m_char);
  5. Substring()
    截取字符串。返回截取后的子串。
    使用:
    字符串变量.方法名(开始截取的位置);
    字符串变量.方法名(开始截取的位置,截取多长);
    例如:name.Substring(2); //从角标为 2 的位置,截取到最后;
    name.Substring(2,2); //从角标为 2 的位置,截取 2 个字符;
  6. IndexOf()
    查找某个字符串在字符串中第一次出现的位置。 返回所在的索引位置值。如果没有找到,返回-1。
    使用:name.IndexOf(“on”);
  7. LastIndexOf()
    查找某个字符串在字符串中最后一次出现的位置。 返回所在的索引位置值。如果没有找到,返回-1。
    使用:name.IndexOf(“on”);
  8. ·StartsWith() `
    判断是否以…字符串开始。如果是,返回真;如果不是,返回假。
    使用:字符串变量.方法名(子字符串);
    演示:name.StartsWith(“Mo”);
  9. EndsWith()
    判断是否以…字符串结束。如果是,返回真;如果不是,返回假。
    使用:字符串变量.方法名(子字符串);
    演示:name.EndsWith(“key”);
  10. Replace()
    字符串中的某个字符串替换成一个新的字符串。返回新的字符串。
    使用:字符串变量.方法名(旧字符串,新字符串);
    演示:name.Replace(“Mon”, “CODE”);
  11. Contains()
    判断某个字符串中是否包含指定的字符串。如果包含返回真,否则返回假。
    使用:字符串变量.方法名(子字符串);
    例如:name.Contains(“key”);
  12. Trim()
    去掉字符串中前后空格。返回处理后的字符串。
    使用:字符串变量.方法名();
    例如:address.Trim();
  13. TrimEnd()
    去掉字符串结束后的空格。返回处理后的字符串。
    使用:字符串变量.方法名();
    例如:address.TrimEnd();
  14. TrimStart()
    去掉字符串开始前的空格。返回处理后的字符串。
    使用:字符串变量.方法名();
    例如:address.TrimStart()
  15. IsNullOrEmpty()
    判断一个字符串是否为 Null 或者空。 如果为 null 或者空,返回真;否则返回假。 null 是不占内存空间的,而空字符串(“”)是占内存空间的。
    使用:string.方法名(字符串变量);
    例如:string.IsNullOrEmpty(name);
字符串的特点
  1. 字符串是引用类型 字符串的数据是存储在堆空间,在栈空间中存储了该数据的引用地址。
  2. 字符串是不可变的 当你给一个字符串变量重新赋值时,旧值并没有销毁,而是重新开辟一块空间来 存储新值。
  3. 字符串可以看做是是自读的字符数组
    使用字符串变量[下标]的形式可以取字符串中指定的字符。
    也可以使用 for 循环变量数组。
    字符串变量.Length;可以取得字符串字符的个数。

二:字符串操作之 StringBuilder

  1. 字符串的缺点
    当需要对一个字符串变量重复赋值时,在内存中会产生大量的垃圾数据信息。 当重复赋值的频率很高时,执行的效率就会降低。

StringBuilder是一个类。
SB 类型的变量是引用类型。 StringBuilder 类型的“字符串变量”,一直操作同一块内存空间,不会产生 垃圾数据,且执行效率远远高于 string 类型的字符串变量。

StringBuilder 使用方法

  1. 创建 StringBuilder 类型的变量
    StringBuilder sb = new StringBuilder(); //创建一个对象。
    注意:StringBuilder 依赖 System.Text 命名空间。
  2. 往 sb 中追加数据
    sb.Append(i); //追加数据。
    sb.ToString(); //将 sb 转成字符串形式。
  3. 清空 sb 中的数据
    sb.Clear(); //将 sb 清空。

StringBuilder 效率测试

  1. Stopwatch 类
    Stopwatch,秒表计时器,用来记录程序运行的时间。
    注意:Stopwatch 依赖 System.Diagnostics 命名空间。
  2. 创建 Stopwatch 类型对象
    Stopwatch sw = new Stopwatch();
    sw.Start(); //计时器开始。
    sw.Stop(); //计时器结束。
    sw.Elapsed; //开始到结束之间的时长。

三: 枚举类型

枚举定义在 namespace 下,这样在当前的命名空 间下,所有的类(class)都可以使用该枚举。

public enum 枚举名 {1,2,
	值 N
}
  1. 使用枚举类型
    枚举类型 变量名 = 枚举类型.值

四:结构体类型

  1. 什么是结构体?
    结构体:struct
    结构体是一种值类型,通常用于封装一些小型变量数据。
    结构体和我们后续要着重讲解的“对象”有很多类似和一样的地方,可以把结构 体当成一个迷你版的对象来使用。
  2. Untiy3D 中的结构体
    在 Unity3D 中提供了很多结构体类型的数据。
    比如:Vector3(三维向量), Color(颜色),Quaternion(四元数),Ray(射线)等等

声明结构体:

 public struct 结构体名称 
 { 
 	public 数据类型 变量名;
  	public 数据类型 变量名;
   	public 数据类型 变量名; 
 }

使用结构体
创建结构体类型的变量:
结构体类型 结构体变量名 = new 结构体类型();
Person monkey = new Person();
给结构体赋值:
结构体变量名.变量名 = 值;
monkey.age = 27;
结构体取值:
结构体变量名.变量名;
monkey.age;

五:面向对象基础之类与对象

1. 类

在我们的程序中,描述某个具体的物体(比如苹果)特征,就是类(class)。 我们学习面向对象,其中最关键的一个概念“类”,就是用于描述事物特征的。

类的语法

[访问修饰符] class 类名 
{ 
	类的描述信息;
}

访问修饰符: 用于描述这个类的访问权限,现在可以不写,有默认值;
class: 关键字,用于声明一个类,和之前枚举的 enum,结构体的 struct 作用是一样的。
类的描述信息: 描述这类事物的特征(字段,属性,方法);

2. 对象

通过类实例化出来的就是对象。
对象的语法:
类名 对象名 = new 类名();
Apple a1 = new Apple();
类名: 描述这个对象的类,可以是我们自己定义的,也可以是系统提供的;
对象名:我们要通过这个类创建出来的一个具体的个体的名称;
new:关键字,实例化的意思,new 类名() 就是实例化一个类的对象,通过 这个类创建出一个具体的对象出来。

类与对象的关系
类用于描述一类事物的信息;
对象是这个类中的一个具体的个体。

3. 字段
  • 字段不是新东西,字段就是我们之前一直在用的变量。
    变量在面向对象的类中就 叫做字段。
  • 字段的作用和变量的是一样一样一样的。 都是用于存储一些具体的信息。
  • 字段的语法
    public 数据类型 字段名;
    
    public: 访问修饰符;
    数据类型:就是数据类型,比如 int,string,float,double;
    字段名:说白了就是变量名,在面向对象编程的类中,变量就叫字段。
4. 对象使用方法
  1. 实例化对象 类名 对象名 = new 类名();
  2. 字段的赋值与取值
    赋值:对象名.字段名 = 值;
    取值:对象名.字段名

六:面向对象基础之字段属性

1. 访问修饰符

访问修饰符,又称权限修饰符。 目前我们的类中只有字段,通过这个类实例化出来的的对象,这个对象是可以直 接访问到相应的字段的,因为字段的访问权限是 public。
类是一个模具,对象是使用这个模具制作出来的一个具体的物体。
public:公开的。通过对象名.xxx 的形式可以直接访问到。
private:私有的。通过对象名.xxx 的形式访问不到。

2. 属性

字段是我们对象的核心数据,如果直接public公开的话,容易被恶意赋值。 所以,字段通常使用 private 修饰,这样通过对象名.xxx的形式访问不到。 但是我们又需要通过对象名.xxx的形式对字段存储的数据进行操作。
这个时候就出现了一个新的东西“属性”。
属性的作用是对字段进行保护,我们将属性设为 public,可以直接访问,然后 属性保护的字段设置成private,我们通过属性间接的操作字段。
属性的语法:

public 数据类型 属性名 
{ 
	get{return 字段名;}
	set{字段名 = value;}
}

数据类型:和要保护的字段的数据类型一样;
属性名:和字段名一样,只不过首字母要大写;
get:当通过属性名取值的时候,会自动调用 get 中的代码;
set:当通过属性名给字段赋值的时候,会自动调用 set 中的代码; value:也是系统关键字,代表赋给属性的值;
get 和 set 本质上就是两个函数。

3. 命名空间

命名空间,也叫名称空间,英文名是 namespace。
作用:对代码文件进行分类管理。

命名空间的语法:
定义命名空间:namespace 空间名称{ 类 }
引入命名空间:using 空间名称

七:面向对象基础之三种方法

1. 普通方法
  1. 什么是方法?
    方法就是函数,在面向对象编程的类中,函数称之为方法。 方法就是我们在 C#语法基础课程中讲解的函数,使用语法完全一样
  2. 什么是普通方法
    普通方法,就是普通函数。
    在类中的作用是对对象的“行为”进行描述。
    行为:也就是说这个对象能干什么。
  3. 普通方法语法
访问修饰符 返回值 方法名(参数列表) 
{
	方法的具体功能代码;
}

public 修饰的普通方法我们可以使用:对象名.方法名()形式调用;
private 修饰的普通方法无法通过对象名.方法名()的形式调用

2. 构造方法
  1. 什么是构造方法?
    首先它是一个方法,然后它具有“构造”的作用,所以称之为构造方法。
    简单点说,构造方法可以对实例化出来的对象进行初始化。
  2. 构造方法的语法要求
public 类名() 
{
	构造函数代码;
}

①构造方法要用 public 修饰,不能用 private 修饰;
②构造方法没有返回值,且连 void 也不能写;
③构造方法的方法名字必须跟类名一样;
④构造方法是可以有重载的。

构造方法什么时候被调用?
当我们使用 new 关键字实例化一个对象的时候,会首先执行构造方法。

  1. this 关键字
    this 代表当前类的对象。
  2. 注意事项
    当我们的类中不写构造方法的时候,在代码编译后,系统会自动给它添加一个空 构造方法,如果我们写了一个构造方法,默认的“空构造方法”就不会存在。
3. 析构方法
  1. 什么是析构方法?
    和构造方法正好相反,构造方法用于初始化一个对象,析构方法常用清理一个对象,往往干的是“善后”的事情

  2. 析构方法的语法

    ~类名() 
    {
    	析构方法代码体;
    }
    

①析构方法不能有任何参数;
②析构方法无返回值也无访问修饰符;
③析构方法由系统自动调用;
④析构方法可以不写。

八: 面向对象基础之堆栈关系

1. 对象赋值演示

使用 Person 类创建一个 p1 对象,将 p1 对象赋值给 p2。
对象这种“数据”也是引用类型。 赋值的过程是传递的堆空间中的引用地址,p1 和 p2 指向了同一个堆空间地址, 通过 p1 或 p2 修改了对象中的数据,两个对象都会同时发生改变的。

2. 对象的实例化过程
Person p1 = new Person("Monkey", 22, Gender., "山东"); 
Person p3 = new Person();

我们现在实例化对象,有两种方式:
第一种就是调用有参的构造方法实例化对象。
第二种就是调用无参的构造方法实例化对象。
所以:我们在写类的时候,往往都先写一个无参的构造方法,然后在写其他的有 参的构造方法。

那么这个 “new”实例化关键字到底做了什么?
①在内存(堆空间)中开辟了一块空间;
②在开辟出来的这个空间中创建对象数据;
③调用对象的构造方法进行对象的初始化。

3. 面向对象编程

何为面向对象编程那?
简单点说,我们游戏中的一切,都是对象。主角是对象,Boss 是对象,小怪也 是对象。 为了创建这些对象,我们需要实现针对不同的对象写出相应的类。在类中规划好 这个对象的基本信息,和对象的功能作用。 然后实例化对象,对象与对象之间进行相应的交互。

九:继承

1. 继承简介
  1. 什么是继承?
    面向对象开发有三大特性(特点 / 特征):封装,继承,多态。
    将一堆类中的一些共有的“成员”单独抽取出来,作为一个父类,然后这一堆类 继承这个父类,共享父类的资源,这就叫做继承。
  2. 继承的好处
    ①优化代码结构,让类与类之间产生关系(人不是孤立存在的,类也一样);
    ②提高代码的复用性,便于阅读(写更少的代码,干更多的活);
    ③为“多态”提供前提(多态是面向对象最复杂的一个特性)。
2. 继承语法格式

语法格式:
子类继承父类,使用“:”冒号关键字符。

class 子类:父类
{ 
	//类成员;
}
3. 子类继承父类构造方法
4.子类继承父类哪些成员?

继承的效果 子类继承父类,也就意味着在子类中可以访问到父类中定义的成员。 那么在父类中定义的成员(字段,属性,方法)哪些在子类中可以访问到,哪些 访问不到那??

  1. 字段 字段可以使用 private 和 public 进行修饰,但 80%的时候使用 private 修饰。
    private 修饰的字段,我们在子类中访问不到;
    public 修饰的字段,我们在子类中可以访问到,使用 base.字段名。
  2. 属性 属性可以使用 private 和 public 进行修饰,但 80%的时候使用 public 修饰。
    private 修饰的属性,我们在子类中访问不到;
    public 修饰的属性,我们在子类中可以访问到,使用 base.属性名。
  3. 普通方法 普通方法可以使用 private 和 public 进行修饰。
    private 修饰的普通方法,我们在子类中访问不到;
    public 修饰的普通方法,我们在子类中可以访问到,使用 base.方法名()。
  4. 构造方法 构造方法可以使用 private 和 public 进行修饰。但 99%的时候使用 public 修 饰,只有在使用单例模式的时候才使用 private 修饰。
    private 修饰的构造方法,我们在子类中访问不到;
    public 修饰的构造方法,我们在子类中可以访问到,使用 base()。
5.继承的堆栈关系

十: 多态

1. 多态简介

什么是多态?
面向对象开发有三大特性(特点 / 特征):封装,继承,多态。
在继承关系的前提下,实例化出不同的对象,这些对象调用相同的方法,但是却 表现出不同的行为,这就叫做多态。
在 C#语言中体现多态有三种方式:虚方法,抽象类,接口。

2. 多态之虚方法语法
  1. 什么是虚方法?
    在父类中使用 virtual 关键字修饰的方法,就是虚方法。
    在子类中可以使用 override 关键字对该虚方法进行重写。

  2. 虚方法语法
    父类:

     public virtual 返回值类型 方法名() 
     {
     	方法体代码;
     }
    

    子类:

    public override 返回值类型 方法名() 
    {
    	方法体代码;
    }
    

    例:老虎和猫继承同一个父类,实现“叫”虚方法。

  3. 虚方法使用细节
    ①将父类的方法标记为虚方法,就是在父类方法的返回值前加 virtual 关键字, 表示这个方法可以被子类重写。
    ②子类重写父类方法,在子类的方法的返回值前加 override 关键字。
    ③父类中的虚方法,子类可以重写,也可以不重写。
    ④父类中用 virtual 修饰的方法,可以用于实现该方法共有的功能(比如初始化 该方法),然后在子类重写该方法时,使用 base 关键字调用父类中的该方法。

3. 多态只抽象类语法
  1. 抽象方法
    虚方法->抽象方法
    父类里面用 virtual 关键字修饰的方法叫做虚方法,子类可以使用 override 重写该虚方法,也可以不重写。
    虚方法还是有方法体的,当我们父类中的这个方法已经虚到完全无法确定方法体的时候,就可以使用另外一种形式来表现,这种形式叫抽象方法。
    抽象方法语法
    抽象方法的返回值类型前用关键字 abstract 修饰,且无方法体。
    抽象方法必须存在于抽象类中。
  2. 抽象类
    抽象类语法:
    在定义类的关键字 class 前面加 abstract 修饰的类就是抽象类。
    子类继承抽象类,使用 override 关键字重写父类中所有的抽象方法。
    抽象类注意事项
    • 抽象类中不一定要有抽象方法,但是抽象方法必须存在于抽象类中。
    • 抽象类不能被实例化,因为抽象类中有抽象方法(无方法体),如果真能实例 化抽象类的话,调用这些无方法体的方法是没有任何意义的,所以无法实例化。
  3. 使用场景
  • 当父类中的方法不知道如何去实现的时候,可以考虑将父类写成抽象类,将 方法写成抽象方法。
  • 如果父类中的方法有默认实现,并且父类需要被实例化,这时可以考虑将父 类定义成一个普通类,用虚方法实现多态。
  • 如果父类中的方法没有默认实现,父类也不需要被实例化,则可以将该类定 义为抽象类。
4. 多态之接口语法
  1. 接口语法
    • 抽象类->接口
      当抽象类中所有的方法都是抽象方法的时候,这个时候可以把这个抽象类用另外 一种形式来表现,这种形式叫接口。
    • 语法格式要求
      接口使用 interface 关键字定义,没有 class 关键字,接口名一般使用“IXxxx” 这种方式进行书写,在一堆脚本中通过名字判断,I 开头的都是接口。 接口中不能包含字段,但是可以包含属性(?没有字段,如何写属性那??)
      接口中定义的方法不能有方法体,全是抽象方法,但又不需要用 abstract 修饰;
      接口中的成员不允许添加访问修饰符,默认都是 public;
    • 接口注意事项
      接口中所有的方法都是抽象方法,所以接口不能被实例化;
      一个类可以实现多个接口,被实现的多个接口之间用逗号分隔开;
      一个接口可以继承多个接口,接口之间也要用逗号分隔。
  2. 使用场景
    接口是一种能力,是一种规范,当我们对现在已经存在的类的继承关系进行功能 扩展的时候,就可以使用接口来完成相应的工作。
  3. C#属性
    • 常规属性
      先定义一个私有的字段,然后在为这个私有字段封装一个公开的属性,在属性中 实现 get 和 set 两个方法,这种方式叫做常规属性。
      当我们使用常规属性的时候,可以在 get 和 set 方法中,编写逻辑代码对取值 和赋值进行逻辑的校验。 这种方式是我们之前一直在使用的方式。
    • 自动属性
      在某些情况下,属性的 get 和 set 只是完成字段的取值和赋值操作,而不包含 任何附加的逻辑代码,这个时候可以使用自动属性。
      public int Age { get; set; }
      
      当我们使用自动属性的时候,就不需要再写对应的字段了,C#编译器会自动给 我们的自动属性提供一个对应的字段
      注意: 在接口中使用属性,就要写自动属性的格式,因为接口中不支持字段。
  4. 接口案例
    • 模拟电脑 USB 接口 所有的电脑上都有 USB 接口,这些 USB 接口存在的目的是为了方便对电脑进 行功能上的扩展,可以在这些接口上插 U 盘,移动硬盘,手机,外置光驱等等。 之所以可以在 USB 接口上插入这些外置设备,是因为这些设备的接口都符合 USB 接口的协议,符合了这个协议,才能使设备可以正常的和电脑连接。
    • 编码实现: USB 是一个接口。 U 盘,移动硬盘,手机是具体的产品,这些产品在满足了自身功能的前提后,还需要实现这个 USB 接口规定的功能。
5. 多态之虚方法抽象类接口对比

使用场景对比:

  • 虚方法:父类中的个别方法用虚方法实现,然后允许子类在有需要的情况下重写 这些虚方法。
  • 抽象类:父类定义一系列的规范,子类去把父类里面定义的这些规范全部实现。
  • 接口:是一种功能的扩展,是在原有的类的继承关系以外的新功能的扩展。
6. 面向对象六大原则

在使用面向对象思想进行程序设计开发过程中,有六大原则需要注意
六大原则如下:
①单一职责原则;
②开闭原则;
③里氏转换原则;
④依赖倒置原则;
⑤接口隔离原则;
⑥迪米特原则;

里氏转换原则

  1. 何为里氏转换
    ①子类对象可以直接赋值给父类变量;
    ②子类对象可以调用父类中的成员,但是父类对象永远只能调用自己的成员;
    ③如果父类对象中装的是子类对象,可以将这个父类对象强转为子类对象;

  2. is 和 as
    is 和 as 两个关键字都可以进行类型转换。
    is:如果转换成功,返回 true,失败返回 false;
    as:如果转换成功,返回对应的对象,失败返回 null。

总结:

  1. 关于多态的实现方式已经介绍了虚方法,抽象类两种方式了。
  2. 多态的使用前提,是建立在继承的关系之上的,也就是说必须要先有继承关 系,然后才会出现多态。
  3. 面向对象的封装,继承,多态,都是我们后期规划代码结构的基本思想。
  4. 后续使用 Unity 开发一款游戏,大点的项目可能会有几百个独立的脚本文 件,这么多的脚本文件,如果没有一个代码结构框架来管理的话,项目十有八九 是会中途夭折的。

在游戏中会出现很多种不同用途的 NPC,这些 NPC 有各自的存在的价值和作 用,同时又具备一些共性的东西。在开发 NPC 系统的时候,往往是需要提取共 性,独立出一个父类,然后子类继承实现不同作用的 NPC。 分析:
任务 NPC,商贩 NPC,铁匠 NPC,三种 NPC 的种类。
共有属性:npc 的名字,npc 的类型;
共有方法:都能和玩家交互(交谈);

十一:封装之五种访问修饰符

1. 五种访问修饰符
  1. public [公开访问] 公开的访问权限。
    当前类,子类,实例对象,都可以访问到。
  2. private [私有访问] 私有的访问权限。
    只能在当前类内部进行访问使用;子类,实例对象,都访问不到。
  3. protected [保护访问] 受保护的访问权限。
    只能在当前类的内部,以及该类的子类中访问;实例对象访问不到。
  4. internal [内部访问]
    只能在当前程序集(项目)中访问; 在同一个项目中 internal 和 public 的访问权限是一样的。
  5. protected internal [内部保护访问]
    protected + internal 的访问权限。
2. 使用场合
  1. 修饰类
    能够修饰类的访问修饰符只有两个,public 和 internal;
    类的默认访问修饰符是 internal。
  2. 修饰类成员
    五种访问修饰符都可以修饰类中的成员;
    类中的成员默认访问修饰符是 private。

十二:静态

静态之字段与属性
  1. static 关键字
    static 关键字,用于修饰类,字段,属性,方法,构造方法等。
    被 static 修饰的类称之为“静态类”;
    被 static 修饰的成员称之为“静态成员”,被修饰过的成员分别称为: 静态字段,静态属性,静态方法,静态构造方法。
  2. 静态字段
  • 概念
    被 static 关键字修饰的字段,叫做“静态字段”。
    静态字段不属于任何对象,只属于类,必须要用 类名.静态字段名 进行访问, 反过来通过 对象名.静态字段名 的方式是访问不到静态字段的。
  • 注意事项
    静态字段是可以重新赋值的,类名.静态字段名 = 新的值; 静态字段存储的数据在内存中只有一份;
    实例(对象)字段在内存中会有 N 份,有多少对象就会有多少实例字段;
  1. 静态属性
  • 概念
    被 static 关键字修饰的属性,叫做“静态属性”。
    静态属性用于对静态字段进行封装,并保证静态字段值的合法性;
    静态属性使用 类名.静态属性名 进行访问;
  • 注意事项
    静态属性不能用于封装非静态字段,因为静态的类成员是先于非静态的类成员存 在的。
    在还没有对象之前,静态类成员就已经存在了。
静态之方法与类
  1. 静态普通方法
    • 概念
      被 static 修饰的方法,叫做静态方法。
      直接使用 类名.静态方法名 进行访问。
    • 注意事项
      控制台程序的 Program 入口类中的 Main 函数就是一个静态方法;
      在静态方法中不能调用非静态方法。
  2. 静态构造方法
    • 概念
      静态构造方法的作用是用于初始化静态成员。
      一个类只能有一个静态构造方法,该静态方法没有任何访问修饰符,也没有参数。
      可以定义在静态类中,也可以定义在非静态类中。
    • 注意事项
      静态构造方法会在程序创建第一个实例,或者引用任何静态成员之前,完成类中 静态成员的初始化。
  3. 静态类
    • 概念
      当类中的成员全部是静态成员的时候,可以把这个类声明为静态类。
      声明静态来需要在 class 关键字前加静态关键字 static。
    • 注意事项
      静态类中不能存在非静态(实例)成员;
      静态类不能实例化对象。
  4. 静态总结
    先有静态成员,后有实例成员;
    后出现的,可以调用先出现的;
    而先出现的则不能调用后出现的。
静态之单例设计模式
  1. 设计模式
    在程序开发过程中经常会遇到一些典型的问题,在对这些问题进行处理解决 的过程中,慢慢的整理出来了一套系统的解决方案,这套方案称之为“设计模式”。
    代表性的有《GoF23 种设计模式》。
  2. 单例设计模式
    • 何为单例?
      设计一个类的时候,需要保证整个程序在运行期间只存在一个实例对象。
      解决这个问题,我们就需要用到“单例(模式)”。
    • 注意事项
      单例设计模式是用于非静态类中的,在静态类中写单例无意义。
// 声明一个静态且私有的这么一个当前类类型的字段; 
private static ClassName instance; 
// 创建私有无参构造方法,保证外部无法实例化这个类; 
private ClassName() { } 
// 创建一个静态方法,用于创建此类的唯一对象。 
public static ClassName Instance() 
{ 
	if (instance == null) 
	{ 
		instance = new ClassName();
	}
	return instance;
}
十三:嵌套类匿名类与密封类
1. 嵌套类
  1. 概念
    在 C#中可以将一个类定义在另一个类的内部;
    外面的类叫“外部类”,内部的类叫“嵌套类”;
    嵌套类和普通类相似,只是声明的位置比较特殊。
  2. 注意事项
    如果想实例化内部类的话,需要使用 外部类名.内部类名 的方式访问到内部类。
2. 匿名类
  1. 概念
    如果某个类的实例对象只会使用到一次,可以使用匿名类的方式创建这个对象。
    不需要定义类,我们就可以创建一个对象。
    这样的类一般用于存储一组只读属性。
    var p = new { Name = "Monkey", Age = 100 };
    
3. 密封类
  1. 概念
    被 sealed 关键字修饰过的类不可以被继承,也就是说不能有子类;
    这样的类,通常被称之为“密封类”。

十四:装箱与拆箱

1. Object 类
  1. 概念
    在 C#语言中,Object 类是所有类的父类,在 C#中所有的类(内置的,我们 自己创建的)都直接或者间接继承自 Object 类。
    Object 是类,object 是类型。(类与系统关键字的语法颜色区别)
  2. 重写 ToString 方法
    我们经常会在自己的类中重写 ToString 方法,将类中的信息打印输出。 目的是:辅助调试和开发。
2. 装箱与拆箱
  1. 概念
    装箱:值类型–>引用类型
    拆箱:引用类型–>值类型
    两种类型只有存在继承关系的时候,才可能出现装箱或拆箱操作。
  2. 注意事项
    装箱和拆箱本质上是数据存储在栈空间与堆空间之间变更,因此频繁的装箱或拆箱会降低运行效率,所以代码中尽量少用装箱或拆箱操作。

十五:预编译指令与对象初始化器

1. 预编译指令
  1. 什么是预编译指令?
    预编译指令也叫预处理指令,在程序正式编译之前执行。
    这些指令不会转化为可执行代码中的命令,但是会影响编译过程的各个方面。
  2. 区域指令
    指令格式:
    #region Info 
    ......
    #endregion
    

作用:
优化代码结构,当我们一个脚本文件有 500 行+,1000 行+的时候,一个脚本 文件中会出现大量的字段,属性,方法,各种各样的功能的代码。
如果想要快速的定位某个功能的代码,是很不方便的。这个时候我们可以使用区域指令,进行代码折叠。

2. 对象初始化器
  1. 概念
    在一个类中,我们通常使用构造方法来对属性进行赋值,完成对象的初始化。
    但是当一个类中的属性很多很多的时候,不可能为各种情况都定义构造方法,这 个时候可以使用“对象初始化器”来完成属性的赋值。
  2. 语法格式:
    类名 对象名 = new 类名(){属性名 = 值;属性名 =}

在这里插入图片描述

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神小夜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值