虚拟内存总体划分为五大区域:栈区(堆栈),堆区(托管堆),常量,静态(静态初始化,静态未初始化),代码区
* 栈区:有计算机虚拟内存自动进行释放管理,栈区的存储方式为先进后出。用于分配值类型。栈由操作系统进行管理,不受GC(垃圾回收机制)管理。当值类型不在作用域, 其所在的内存空间自动释放,栈的执行效率最高。
堆区:用于分配小对象实例(85000),所谓小对象就是小于85000字节的实力对象。 GC堆分三代垃圾管理进行管理,当操作时(垃圾回收的时候),垃圾收集器会对GC堆进行压缩回收。原理有点类似于ios中的autorelease(自动释放池)
大对象堆(large object heap):大对象就是指大小超过85000个字节的实力对象,大部分分配在LOH上,不受GC管理,不会被压缩,只有在完全GC回收时才会被回收
ps:栈的分配是高位-->低位进行扩展
堆的分配是低位-->高位进行扩展
值类型参数与引用参数的本质,值参数是对栈中数据进行拷贝,拷贝出来的数据相当于之前数据的副本,引用类型是对栈中数据地址的引用,当值参数为某对象引用时,可以改变该对象的某些值,但是不能将值变成新对象的地址
面向对象之封装
封装特性:
为什么要封装?
属性存在的目的:其实就是巍峨保护类的内部结构不被破坏,达到封装性。
属性的语法格式:
访问修饰符public(必须) +对应字段的数据类型+字段名称(首字母必须大写 )
{
}
属性本身就是一种特殊的方法,他没有返回值,是因为属性内部提供了可以访问该属性的
ref参数:将值类型引用改变为地址引用
值类型作为参数传递的时候,传递的不是本身,而是副本,如果要修改本身的值就需要修改为引用传递
string 虽然本身是引用类型,但是作为参数传递的时候默认是值传递,而不是引用传递。 如果想改变原来的字符串,这个时候就要将值类型改为引用传递,加上ref关键字。 如果你不想改变原来的字符串,就直接传递字符串
object本身就是引用类型,它和字符串不一样,它默认就是引用传递,也就是传递的是地址。
数组作为参数传递时也是引用传递.
out参数:输出到的意思,其实就是保存一个数值在其中
面向对象之继承
继承:
继承使用条件:当你设计类的时候,发现有字段重复。
具有相同特征不同行为的可以抽取出来,单独称为一个类,这个类供派生类使用。
简称:基类。
在现实生活中继承的关系有很多
1.儿子继承父亲
2.黄焖鸡米饭
3....
在程序中使用关键符号:表示继承
格式:(:+类)
这个类是要继承的类
继承关系中的特点:
1.子类可以继承父类中的公有字段
2.子类可以继承父类中的公有属性
3.子类可以继承父类中的公有函数
4.父类不能拥有子类的字段/方法/属性/索引器
5.在C#中不支持多重继承,也就是一个类只能继承一个类,如果你向支持多继承,那么请使用interface
继承关系中的构造函数
1.在继承关系中首先会调用父类的构造函数,然后再调用子类的构造函数
2.在继承关系中,子类初始化对象时,先调用父类的构造函数,然后再看子类构造函数有没有显式(:base()关键字)通知编译器指定调用父类的哪个构造函数,如果没有,那么默认去调用父类的无参数构造函数.此时如果父类重写了带有参数的构造函数,程序编译不通过,那么解决的办法就是给父类添加无参数构造函数或者在子类构造函数中声明指定调用的哪个父类的构造函数
public class Boss
{
public string name;
public string jineng;
public Boss ()
{
Console.WriteLine ("父类构造方法被调用");
}
public Boss(string name,string jineng){
this.name = name;
Console.WriteLine (name);
Console.WriteLine ("父类构造方法被调用2");
}
}
class Boss_x:Boss
{
public Boss_x(string name,string jineng):base(name,jineng)//将参数传递给指定父类构造方法
{
Console.WriteLine ("子类构造方法被调用");
}
public Boss_x()
{
}
public static void Main()
{
Boss_x b = new Boss_x ();//当执行这段代码时,调用父类无参数的构造方法
Boss_x b1 = new Boss_x("das","a");//当这段代码执行时,调用父类有参数的构造方法
}
}