值类型变量直接把变量的值保存在堆栈中,引用类型的变量把实际数据的地址保存在堆栈中,而实际数据则保存在堆中。
注意,堆和堆栈是两个不同的概念,在内存中的存储位置也不相同,堆一般用于存储可变长度的数据,如字符串类型;而堆栈则用于存储固定长度的数据,如整型类型的数据int(每个int变量占用四个字节)。由数据存储的位置可以得知,当把一个值变量赋给另一个值变量时,会在堆栈中保存两个完全相同的值;而把一个引用变量赋给另一个引用变量,则会在堆栈中保存对同一个堆位置的两个引用,即在堆栈中保存的是同一个堆的地址。在进行数据操作时,对于值类型,由于每个变量都有自己的值,因此对一个变量的操作不会影响到其它变量;对于引用类型的变量,对一个变量的数据进行操作就是对这个变量在堆中的数据进行操作,如果两个引用类型的变量引用同一个对象,实际含义就是它们在堆栈中保存的堆的地址相同,因此对一个变量的操作就会影响到引用同一个对象的另一个变量。
4)结构和类的区别
1) 结构是一个值类型,保存在栈上,而类是一个引用类型,保存在受管制的堆上。 2) 对结构中的数据进行操作比对类或对象中的数据进行操作速度要快。
3) 一般用结构存储多种类型的数据,当创建一个很多类或对象共用的小型对象时,使用结构效率更高。
5)抽象方法和虚方法的区别 抽象方法:
使用abstract关键字 public abstract bool Withdraw(…); 抽象方法是必须被派生类覆写的方法。 抽象方法是可以看成是没有实现体的虚方法
如果类中包含抽象方法,那么类就必须定义为抽象类,不论是否还包含其它一般方法
虚方法:
使用virtual关键字 public virtual bool Withdraw(…);
调用虚方法,运行时将确定调用对象是什么类的实例,并调用适当的覆写的方法。 虚方法可以有实现体
其实大家首先要搞清楚,虚方法与多态性关系密切,虚方法允许派生类完全或部分重写该类的方法,需写方法体。抽象类中可以包含抽象方法与一般的方法,抽象类不可以new,抽象方法只是一个定义,没有方法体,也就是没有{},也不要在里面写内容。它们两个相像的一点是都用override重写。
14.结构体
结构成员可以是各种数据类型的变量、构造函数、方法、属性和索引器等。定义结构的格式如下:
[修饰符] struct 结构名 [:接口名列表] { …/结构成员定义}
除了含有常规的方法外,结构还可以有构造函数,但构造函数必须包含参数。对于结构体的使用有两种:用new初始化和直接定义结构体变量。用new的原因是可以调用结构体的构
造函数。
结构可能看似类,但存在一些重要差异,应引起注意。首先,类为引用类型,而结构为值类型。使用结构,您可以创建行为类似内置类型的对象,同时享有它们的好处。在类上调用“新建”(New) 运算符时,它将在堆上进行分配。但是,当实例化结构时,将在堆栈上创建结构。这样将产生性能增益。而且,您不会像对待类那样处理对结构实例的引用。您将直接对结构实例进行操作。鉴于此原因,向方法传递结构时,结构将通过值传递,而不是作为引用传递。 同时,在结构中不允许给一个实例变量赋初值。
对于结构,不像类那样存在继承。一个结构不能从另一个结构或类继承,而且不能作为一个类的基。但是,结构从基类对象继承。结构可实现接口,而且实现方式与类实现接口的方式完全相同。
下面的这个例子显示了类是引用类型而结构是值类型。
namespace InterfaceTest {
classStructTest { } classTheClass { publicint x; }
structTheStruct { publicint x; }
classTestClass {
publicstaticvoid structtaker(TheStruct s) {
s.x = 5; }
publicstaticvoid classtaker(TheClass c) {
c.x = 5; }
publicstaticvoid Main() {
TheStruct a = newTheStruct(); TheClass b = newTheClass(); a.x = 1; b.x = 1; structtaker(a); classtaker(b);
Console.WriteLine(\, a.x); Console.WriteLine(\, b.x); Console.ReadLine(); } } }
15.枚举
枚举数据类型可以用来创建只有有限几个取值的变量,这种数据类型允许我们用日常习惯使用的符号来表示一组整数值。定义枚举类型的格式如下:
[代码属性] [修饰符] enum 枚举名 [:数据类型] {…/枚举成员列表}
如果没有指定枚举成员的数据类型,则整数类型将作为枚举值的数据类型。 测试代码:
namespace InterfaceTest {
classEnumClass { }
classAppEnum {
publicenumWeekdays : long {
Sun=-1,Mon,Tues,Wed,Thur,Fri,Sat }
publicstaticvoid Main() {
Console.WriteLine(\, Weekdays.Sun); Console.WriteLine(\, (long)Weekdays.Sun); Console.WriteLine(\, (long)Weekdays.Mon); Console.WriteLine(\, (long)Weekdays.Tues); Console.WriteLine(\, (long)Weekdays.Wed); Console.WriteLine(\, (long)Weekdays.Thur); Console.WriteLine(\, (long)Weekdays.Fri); Console.WriteLine(\, (long)Weekdays.Sat); Console.ReadLine();
} } }
2.Employee的接口怎么简化