1. 构造函数
- 作用:帮助我们初始化对象(给对象的每个属性依次的赋值),在创建对象的时候执行。
- 特点:
- 构造函数没有返回值,也没有void
- 构造函数的名称必须和类名一样
- 构造函数可以重载
- 类中会有一个默认的无参构造函数,当写了一个新的构造函数后,默认的会被覆盖。
- 静态构造函数既没有访问修饰符,也没有参数。
- 一个类只能有一个静态构造函数。
2. 析构函数
- 当程序结束的时候,析构函数才会执行,帮助释放资源;
- 如果不使用析构函数,垃圾回收器自动回收资源。
~ClassName()
{
...
}
3. new关键字
- 作用1:
- 在内存中开辟一块空间
- 在开辟的空间中创建对象
- 调用对象的构造函数进行初始化对象
- 作用2:
- 隐藏从父类哪里继承过来的成员
4. this关键字
- 作用:
- 代表当前类的对象
- 在类当中显示的调用本类的构造函数( :this)
//demoClass为构造函数
public demoClass(parameter1,paramater2,parameter3)
{
this.para1 = parameter1;
this.para2 = parameter2;
this.para3 = parameter3;
}
public demoClass(paramater2):this(parameter1,paramater2,parameter3)
{
this.para2 = parameter2;
}
5.StringBuilder
String是引用类型,每一次赋值都会重新开辟一个内存空间,当一个字符串需要多次赋值时会耗费大量内存空间和时间,此时可以使用StringBulder,在多次赋值时使用的是同一块内存空间,最后调用.ToString()转成字符串类型。
6.访问修饰符
- public:公共的、公开的
- private:私有的,只能在当前类的内部访问,类中的成员不加访问修饰符默认为private
- procteced:受保护的,可以在当前类及其子类的内部访问
- internal(C#):在当前项目中都可以访问
- procteced internal (C#)
7.值类型与引用类型
- 值类型:int double char decimal bool enum struct
- 引用类型:string 数组 自定义类 集合 object 接口
8. 里氏转换
1.子类可以赋值给父类
//存在一个父类Parent 子类Children
Children c = new Children();
Parent p = c;
//等同于
Parent p = new Children();
2.如果父类中装的是子类对象,那么可以将这个父类强制转为子类对象
//接上段代码 p是装着子类对象的父类对象
Children cc = (Children)p;
3.is / as 类型转换
- is:表示类型转换,如果能转换成功,则返回一个true,否则返回一个false
//如果父类p能转换成子类 则返回true
if(p is Children)
{
Children cc = (Children)p;
...
}
- as:表示类型转换,如果能转换成功,则返回对应的对象,否则返回一个null
//如果父类p能转换成子类 则返回对应的对象
Children c = p as Children;
9.装箱和拆箱
- 装箱:将值类型转换为引用类型
- 拆箱:将引用类型转换为值类型
- 注意:装箱拆箱回耗费大量的时间,应该尽量少使用
//ArryLsit中装的是引用类型,int是值类型,将int装入ArryLsit中发生了装箱
ArryLsit list = new ArryList();
for (int i = 0; i<100000; i++)
{
//共有100000次装箱
list.add(i);
}
//此时list是泛型集合对象,需要的参数是int类型,循环过程中没有装箱过程
List<int> list = new List<int>()
for (int i = 0; i<100000; i++)
{
//共有0次装箱
list.add(i);
}
//比较上述两种方式,经过装箱的远比不经过装箱的耗时长
10.序列化与反序列化
- 序列化:将对象转换为二进制
- 反序列化:将二进制转换为对象
作用:数据传输(数据传输过程中是以二进制进行的,传输完毕再转换为对象)
11.接口
- 接口是一种规范,接口存在的意义是为了多态
- 接口不能被实例化
- 接口的成员不能加“访问修饰符”,默认为public,不能修改
- 接口中的成员不能有任何实现
- 接口中只能由方法、属性、索引器、事件,不能有字段和构造函数
- 接口与接口之间可以继承,并可以多继承
- 接口不能继承一个类,类可以继承一个接口
- 只要一个类继承了接口,这个类就必须实现这个接口中的所有成员
- 子类实现接口时,不需要任何关键字,直接实现即可
- 一个类可以同时继承一个并实现多个接口,如果一个子类同时继承了父类A,并实现了接口IA,那么语法上A必须写在IA前面(父类写在接口前面 )
//当一个类中继承的父类或接口有相同的方法,未解决接口的重名问题,应该显示实现接口
public interface IFlyable()
{
void Fly();
}
public class Bird()
{
public void Fly()
{ ... }
}
public Xique : Bird,IFlyable
{
public void Fly
{
//与父类、接口方法同名
//若没有显示实现接口,根据子类必须实现该接口的全部成员的规则,这个方法是实现了接口的,而不是自己的
}
void IFlyable.Fly()
{
//显示实现接口的方法
}
}
12.多态的实现
什么时候用虚方法实现?
- 在多个类中能抽象出一个父类,并且父类中必须有这几个子类中共有的方法,而这个方法知道如何去写,且还需要创建父类对象,用虚方法来实现。
什么时候用抽象类法实现?
- 在多个类中能抽象出一个父类,并且父类中必须有这几个子类中共有的方法,但却不知道如具体如何去写,用抽象类来实现。
什么时候用接口实现?
- 在多个类中找无法抽象出一个父类,但有共同的行为/能力,使用接口实现多态。
虚方法和抽象方法
- 虚方法注意事项:
- 父类中如果有方法需要让子类重写,则可以将该方法标记为virtual
- 虚方法在父类中必须实现,哪怕是空实现
- 虚方法子类可以重写(override),也可以不重写
- 抽象方法注意事项:
- 需要用abstract关键字标记
- 抽象方法不能有任何方法实现
- 抽象成员必须包含在抽象类中,抽象类也可以包含非抽象成员
- 由于抽象成员没有任何实现,所以子类必须将抽象类重写
- 抽象类不能实例化
结构和类的区别
| 结构 | 类 | |
|---|---|---|
| 类型 | 值类型 | 引用类型 |
| 声明 | struct | class |
| 构造函数赋值 | 只能给字段赋值 | 可以给字段和属性赋值 |
| 构造函数 | 重写构造函数不会覆盖原有的默认构造函数 | 重写构造函数会覆盖原有的默认构造函数 |
- 使用:
- 若只是想存储数据,推荐使用结构
- 若想用面向对象的思想来开发程序,推荐使用类