Net学习日记_基础提高_4
结构
1.使用struct关键字来定义1个结构,级别与类保持一致,写在命名空间下面。
2.结构中可以定义:字段、属性、构造函数、也可以通过new关键字创建对象。
结构与类的区别
1.结构中的字段不能赋初始值。
2.无参数的构造函数无论如何C#编译器都会自动生成,所以我们不能为结构定义1个无参数的构造函数。
3.在构造函数中必须要为结构体的所有字段赋值。
4.(属性不一定为字段封装)构造函数中为属性赋值,不认为是对字段赋值,因为属性不一定为字段赋值操作。
5.结构是一个值类型,在传递结构变量的时候,会将结构对象里的每一个字段赋值一份,然后拷贝新的结构变量中。
6.不能定义自动属性,因为自动属性会生成1个字段,而这个字段必须要求在构造函数中,但又不知道这个字段的声明名字。
7.声明结构体对象可以不new关键字。但是这时候结构体对象的字段没有初始值。没有调用构造函数,而构造函数必须为字段赋值
所以通过new关键字创建结构体对象,这个对象的字段就有默认值了。
8.当我们要表示1个轻量级的对象的时候,就可以定义结构,以便提高速度。
根据传值的影响,希望传引用就定义为类,希望传拷贝就定义为结构。
1.栈的访问速度快,但是空间小。
2.堆的访问速度慢,但是空间大。
垃圾回收
托管代码与非托管代码
程序集在CLR的保护下,进行运行。应用程序域防止你访问其他类型的空间
被CLR管理的代码叫做托管代码,反之,不被CLR管理的代码叫做非托管代码。
像C/C++上得到自己开辟文件域。但你访问不了NET应用程序的地址,因为受保护。
应用程序域:将net程序保护起来,独立起来
栈啥时候开始回收呢?
分配在栈空间的变量,一旦执行完其所在作用域"{ }"完毕的时候,则立即回收。
堆呢?
储存在堆里面的对象,当没有任何变量引用它时候,这个对象就被标记为“垃圾对象”,等待垃圾回收器回收。
GC会定时清理堆空间的垃圾对象
GC清理垃圾对象的频率。程序无法决定,CLR会自动控制。
不同代的不断开辟空间,但啥时候回收空间呢?
当第0的空间满的时候,在第1代回收第0代的垃圾空间,认为越老的对象,认为其生命周期越长。
当1个对象被标记为“垃圾”的时候,这个对象不一定会被立即回收;
Person p = new Person();
int gen = GC.GetGeneration(p); //得到指定的对象所在的代数
GC.MaxGeneration(); // 返回代数
GC.Collect(); //立即让垃圾回收器对所有的代进行回收。可以指定代的回收
注意:最多只有三代。
析构函数
在对象被GC回收的时候调用析构函数,析构函数往往用来做“清理善后”的工作。
~类名
注意事项:
1.一个类只有一个析构函数
2.析构函数不能被继承或重载
3.析构函数不能被调用,他们是自动被GC调用的。
4.析构函数不能带修饰或参数。
静态成员
1.被static关键字修饰的成员的静态成员
2.静态成员是属于类的,是被static关键字修饰的,可以通过 类.静态成员 来访问
3.实例成员是属于对象的,没有被static关键字的修饰的,可以通过 对象名.实例成员 来访问。(public string name='小花';实例成员)
4.在这个类第一次被加载的时候,这个类下面所有的静态成员都会被加载。
5.静态成员只会创建一次,所以静态成员只有一份。实例成员有多少个对象,就有多少分。
6.静态成员会被创建在静态存储区中。一旦创建,直到程序退出才会被回收。
7.变量需要被共享的时候,方法需要被反复调用的时候,可以把这些成员定义为静态方法。
8.在静态方法中不能直接调用实例成员,因为静态方法被调用时候,对象还有可能不存在。
9.this/base关键字在静态方法中不能使用,因为有可能对象还不存在。
10.可以创建这个类的对象,指定对象的成员在静态方法中操作。
11.在实例方法中,可以调用静态成员,因为这个时候静态成员可定存在。
注意:执行代码只能写在方法中。
类加载,类静态成员的加载?
内存的方法,保存每个类的方法表。
方法表分成两部分:静态区与实例区
对象的类型指针指向实例区。
类名指向静态区。
类加载:访问这个类的时候,将类加载进来,根据类的模板在建立对象。
Common c依据要访问这个类。
Common.num也会访问这个类。
静态变量VS实例变量
1.生命周期不一样
2.存放位置不一样
静态类:类被static关键字修饰。
静态类只能声明静态成员;
静态类不能有实例构造函数。
静态类不能被实例化(new),因为没有实例成员,实例化没有意义。
静态类不能被继承。
静态类的本质是1个抽象的密封类,所以不能被继承也不能被实例化。
如果1个类下卖弄的哦所有成员都需要被共享,那么把这个类定义为静态类
不能声明1个静态类型的变量。
静态构造函数
非静态类也可以有静态构造函数。
这个类的成员第一次被访问的时候,就会执行静态构造函数。
子类从父类继承父类的非私有成员
多个类具有相同的成员,面向对象里面用继承来实现。
继承
class Student : Person
{
1.子类拥有父类的所有成员(但是访问不到父类的私有成员private)
2.但是可以利用protected的来访问其父类私有成员。
}
1.开辟一个合适大小的空间
2.创建子类对象中会为子类对象的字段开辟空间,也会为父类的所有字段开辟空间,只不过父类私有的成员访问不到而已。
3.子类从父类继承父类所有的非私有成员。
base关键字可以显式的调用父类的非私有成员。
4.子类的访问级别不能比父类的高。
创建子类对象的时候
1.调用子类的构造函数
2.调用父类的构造函数
3.执行父类的构造函数
4.执行子类的构造函数
why?
子类的构造函数后面默认加了一个base():通过这个调用父类的无参数的构造函数。
如果父类没有无参数的构造函数,则会报错。
使用base关键字,可以显式的制定子类构造函数调用父类有参的构造函数。
问题1,为啥要调用父类的构造函数?
父类的构造函数会初始化父类属性的值
问题2.为啥父类有限于本类?
避免数据冲突。
继承的特征:
1.单根性;只有一个父类
2.传递性;
Object; 所有的类都直接或者间接的从Object类继承。
啥情况满足继承关系?
不要为了继承而继承!!!
要满足ISA的关系
Student is a Person!
子类与父类在同名成员的时候?
如果创建一个子类对象,调用这个子类对象的同名方法,对调用子类的。
面向对象的总结图