C#高级编程笔记 Day 2, 2016年8月 31日 构造函数
1、构造函数:
实例构造函数(只要创建了对象,就会执行)一般使用 this 关键字区分成员字段和同名的参数。可以把构造函数定义为private 或 protected 。这样不相关的类也不能访问他们。
1 public class MyTest{ 2 private int i; 3 public MyTest(int i){ 4 this.i=i; 5 } 6 }
下面这个例子没有为MyTest 定义任何公有的或受保护的构造函数。这就使MyTest不能使用new 运算符在外部代码中实例化(但可以在MyNumber中编写一个公有的静态属性或方法,以实例化该类)这在下面两种情况下是有用的。
- 类仅用作某些静态成员或属性的容器,因此永远不会实例化它
- 希望类仅通过某个静态成员函数来实例化(这就是所谓的对象实例化的类工厂方法?)
public class MyTest{ private int i; private Mytest(int i){ this.i=i; } }
静态构造函数:编写静态构造函数的一个原因是,类有一些静态字段或属性需要在第一次使用类之前,从外部源中初始化这些静态字段和属性。
在C#中,通常在第一次调用类的任何成员之前执行静态构造函数。
静态构造函数没有任何访问修饰符,在加载类时,由 .Net 运行库调用它。静态构造函数不能带任何参数,一个类只能有一个静态构造函数。
!!无参数的实例构造函数与静态构造函数可以在同一个类中定义。
2、
1 public static readonly Color BackColor;
该静态变量在静态构造函数中进行初始化,把该字段声明为只读类型表示其值只能在构造函数中设置。
3、在一个类中不同构造函数之间的相互调用。通过 this 关键词来进行调用,如果要直接对基类(父类)的构造函数进行调用,则需要使用 base 代替 this
public Car(string description,uint nwheels){ this.desprtion=desption; this.nwheels=nwheels; }
public Car(string description):this(description,4){ // }
4、只读字段:readonly 可以在构造函数中给其赋值,不能在其他地方。
5、【归纳实用】结构 struct :结构是值类型,不是引用类型。存储在栈中或存储为内联。
① 不支持继承
② 对于结构构造函数,编译器总是提供一个无参数的默认构造函数。
③ 结构是值类型,因为结构是值类型,所以 new 运算符与类和其他引用类型的工作方式不同。new 运算符并不分配堆中的内存。而是只调用相应的构造函数,根据传送给它的参数。初始化所有字段。
④ 结构主要用于小的数据结构。但当把结构作为参数传递给方法时,应把它作为 ref 参数传递,以避免性能损失,此时只传递了结构在内存中的地址。
⑤ 结构中禁止使用无参数的构造函数。
★ 结构的继承链是:每个结构派生自System.ValueType类。 System.ValueType 又派生自 System.Object
★ 不能为结构提供其他基类,每个结构都派生自 ValueType。
struct Dimension{ public double Length=1; public double width=2; } //编译错误:
//默认构造函数把数值字段都初始化为 0 ,把引用类型初始化为 null 且总是隐式的给出。 //提供字段的初始值也不能绕过默认构造函数。
6、【专题:C#中堆和栈的理解】
Ⅰ:栈是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义;
堆是程序运行期间动态分配的内存空间你可以根据程序的运行情况确定要分配的堆内存大小。
Ⅱ:存放在栈中时要管存储顺序,保持着先进后出的原则,栈是一片连续的内存域,由系统自动分配和维护。
堆是无序的,一片不连续的内存域,由用户自己来控制和释放,若用户不释放的话,当内存达到一定的特定值时,通过垃圾回收器GC 来回收。
【值类型和指针总是放在它们被声明的地方,不一定被分配在栈上】
调用方法:系统先将一段编码(堆的首部地址)放到栈上,紧接着放置方法的参数。然后代码执行到方法时,查找栈中放该堆首部地址所有参数。并通过堆的首部地址来控制堆。
【引用类型:总是放在堆中】
当我们使用引用类型时,实际上只是在处理该类型的指针,而非引用类型本身。使用值类型的话,则是使用其本身。
1 //Code1: 2 public in AddTest(int value){ 3 int result; 4 result=value+5; 5 return result; 6 }
//Code2: public class MyTest{ public int value; } public MyTest AddTest(int key){ MyInt result =new MyInt(); result.value=key+5; return result; }
C#程序在 CLR 上运行时,内存从逻辑上划分两大块 栈和堆。
Ⅲ、栈和堆的区别。
①、栈通常保存着我们代码执行的步骤,比如在 Code 1 中的 AddTest() 方法。 int value ,int result 变量等。
堆上存放的多是对象和数据。
②、栈内存无需我们管理,也不受GC 管理。当栈顶元素使用完毕,立马释放。
堆则需要GC 清理。
当程序执行的时候,在堆和栈中分配的主要有以下四种类型,
1、值类型 。2、引用类型。 3、指针 。4、指令。
7、弱引用 :弱引用允许创建和使用对象,但是垃圾回收器运行时,就会回收对象并释放内存。
WeakReference 类。
例: WeakReference mathReference =new WeakReference(new MathTest());
8、部分类:partial 关键字允许把类、结构、方法 或接口放在多个文件中。
9、继承:实现继承和接口继承。
不支持多重实现继承 允许多重接口继承
C#中的类可以派生自另一个类和任意多个接口。
10、【结构和类的区别】
①、结构总是派生自 System.ValueType,他们还可以派生自任意多个接口。
②、类总是派生自System.Object 或用户选择的另一个类,他们还可以派生自任意多个接口。
实现继承的语法
class MyTestClass :MyTest{
//....
}