当前位置: 移动技术网 > IT编程>开发语言>.net > net学习之类与对象、new关键字、构造函数、常量和只读变量、枚举、结构、垃圾回收、静态成员、静态类等

net学习之类与对象、new关键字、构造函数、常量和只读变量、枚举、结构、垃圾回收、静态成员、静态类等

2018年03月17日  | 移动技术网IT编程  | 我要评论
1.类与对象的关系

类是对一类事务的统称,是抽象的,不能拿来直接使用,比如汽车,没有具体指哪一辆汽车

对象是一个具体存在的,看的见,摸得着的,可以拿来直接使用,比如我家的那辆刚刚买的新汽车,就是具体的对象

对象是根据类这个模板创建出来的,类里面有哪些特性或者功能对象里面也有,多不得,少不得

 

2.new 一个对象做了哪些事情?

Person person = new Person();new是一个运算符

(1)在内存中开辟一块合适大小的空间

(2)在这个空间里创建对象

(3)调用这个对象的构造函数

(4)返回这个空间的引用地址

 

3.访问修饰符

类的访问修饰符只有public和internal,内部类的访问修饰符可以为private

 

4.属性

属性的本质是一个get和一个set方法,而set方法中定义了一个参数名称为value,所以我们可以在set方法中访问value

属性就是对字段的封装

属性本身不存值,值是存在属性封装的对应的字段中

只要类中的字段要被外界访问,就需要把这个字段封装为属性

 

5.构造函数

(1)构造函数访问修饰符一般情况下是public,没有返回值,方法的名称与类名相同

(2)构造函数在创建这个对象的时候被自动调用,程序员无法手动调用

(3)构造函数有什么用?如果我们希望在创建这个类的对象的同时需要执行一些代码,我们就可以将这些代码写到构造函数中

(4)this关键字代表当前对象,当前运行在内存中的那一个对象,this关键字可以调用其他的构造函数

(5)构造函数调用构造函数:

public Dog(int age,string name):this(age)

{

 

}

public Dog(int age)

{

 

}

调用的时候:Dog dog = new Dog(2,"旺财");程序会先调用Dog(int age)构造函数,然后在调用Dog(int age,string name)构造函数

(6)隐式构造函数:如果程序员没有为类手动添加构造函数,C#编译器在编译的时候会自动添加一个无参数的构造函数

如果添加了构造函数,C#编译器在编译的时候则不会添加

 

6.常量和只读变量

(1)const修饰的数据叫做常量,

常量一旦声明常量的值就不能改变,因为C#编译器在编译的时候声明常量的那句代码不见了,在使用常量的地方就用常量的值替换了

比如

const string name = "小明";

Console.WriteLine(name);

编译之后变为

Console.WriteLine("小明");所以不能赋值

 

readonly修饰的变量只读变量

readonly string name = "小明";

public Person()

{

 

}

编译后

readonly string name ;

public Person()

{

this.name = "小明";

}

const和readonly的区别:

const不能修改值,readonly只能在构造函数中修改值

const在编译的时候就要确定值,readonly在运行时要确定值

 

7.枚举

枚举是一个值类型,每一个枚举成员都对应了一个整型的数值,这个数值默认是从0开始递增

枚举和int类型转换:int a = (int)Direction.South; int i = 2; Direction d = (Direction)i;

枚举和string类型转换:string str = "South"; Direction d = (Direction)Enum.Parse(typeof(Direction),str,true); //true表示忽略 

大小写 

枚举值所对应的数值默认是int类型的,可以在枚举的名字后面加一个冒号来指定这个数值的类型,只能是整型的(byte,short。。。)

如:

enum Direction:byte

{

 

}

好处:限定变量的取值范围,在编码过程中不容易出错

 

8.结构struct

(1)结构中可以定义字段、属性、方法、构造函数,也可以通过new关键字来创建对象

(2)无参数的构造函数无论如何C#编译器都会自动生成,所以我们不能显示的声明无参数的构造函数

(3)在构造函数中必须要为结构体的所有的字段赋值

(4)在构造函数中为属性赋值,不认为是对字段赋值,因为属性不一定是去操作字段

(5)结构是一个值类型,在传递结构变量的时候,会将结构对象里面的每一个字段复制一份,然后拷贝到新的对象中

(6)不能定义自动属性,因为自动属性会生成一个字段,而这个字段必须要求在构造函数中,而我们又不知道这个字段

(7)声明结构体对象可以不new关键字,但是这个时候结构体对象的字段没有初始值,因为没有调用构造函数,而构造函数中必须为字段赋 

值,所以通过new关键字创建的结构体对象的字段就有默认值。

(8)当我们要表示一个轻量级的对象的时候,就可以定位结构以提高速度。根据传值的影响来选择,希望传引用就定义为类,希望传拷贝就 

定义为结构

 

9.垃圾回收

托管代码:被CLR管理的代码

非托管代码:不被CLR管理的代码

应用程序域:当。net应用程序在CLR中运行的时候,CLR会创建一个单独的应用程序域,让。net应用程序在应用程序域中运行

分配在栈空间的变量一旦执行完其所在的作用域(即"{ }"中),这个变量就会CLR立即回收

分配在堆里面的对象没有任何对象引用的时候,这个对象就被标记为“垃圾对象”,等待垃圾回收期回收。

GC会定时的清理堆空间中的垃圾对象,GC清理垃圾对象的频率程序员无法决定,由CLR自动控制

当一个对象被标记为“垃圾对象”的时候,这个对象不一定立即被回收

垃圾回收运行机制:

垃圾回收会根据应用程序的运行情况来使用合适的算法,其中一种算法如下:

CLR会预先开辟一块空间,当创建对象的时候会放在第0代的内存中,当第0代的空间满的时候,GC开始回收第0代,不被标记垃圾的对象会移 

动到第1代内存中,然后第0代空间变为空,当再次创建对象的时候会存储在第0代空间,一直这样重复,第1代空间不满的时候不会回收。当 

第1代空间满的时候,会垃圾回收第1代,然后把老的对象移动到第1代,新对象存储在第0代。第1代到第2代是和第0代到第1代一样,当三代 

都满的时候会报异常说内存溢出

 

GC.GetGeneration(p)获取指定对象是属于第几代,总共有3代,从0开始,0,1,2

GC.Collect();立即让垃圾回收器对所有的代进行垃圾回收

GC.Collect(0);表示对第0代回收GC.Collect(1);表示对第0代和第1代回收

 

Person p = new Person();

GC.GetGeneration(p);值为0

GC.Collect();

GC.GetGeneration(p);值为1

GC.Collect();

GC.GetGeneration(p);值为2

GC.Collect();

GC.GetGeneration(p);值为2

10.析构函数

析构函数不能有访问修饰符,不能有参数,所有不能被继承或重载,在对象被垃圾回收器回收的时候,析构函数被GC自动调用,当没有垃圾 

对象的时候不会被调用,

执行一些清理善后的操作

~Person()

{

 

}

11.静态成员

(1)在这个类第一次被加载的时候,这个类下面所有的静态成员会被加载,静态成员是属于类的,实例成员是属于对象的

(2)静态成员只能被创建一次,所以静态成员只有一份,实例成员有多少个对象就创建多少次

(3)静态成员被创建在静态存储区中,一旦创建直到程序退出才会被回收

(4)什么时候定义为静态的?变量需要被共享的时候,方法需要被反复调用的时候

(5)静态方法中不能直接调用实例成员,因为静态方法被调用的时候,对象有可能没有创建

(6)this/base关键字在静态方法中不能使用,因为有可能对象不存在

(7)在实例方法中可以调用静态成员,因为这个时候静态成员肯定存在

静态成员和实例成员区别:

(1)生命周期不同,静态成员在程序退出时才会被回收,实例成员则在该对象被垃圾回收器回收时才会被回收

(2)存储的位置不同,静态成员存储在静态存储区中,实例成员存储在堆的对象里面

 

12.静态类

(1)静态类中只能声明静态成员

(2)静态类中不能有实例构造函数

(3)静态类中不能被实例化,因为没有实例成员,实例化无意义

(4)静态类不能被继承,因为本质是一个抽象的密封类,所以不能被继承也不能被实例化

(5)如果一个类下面的所有成员都需要被共享,那么就可以把这个类定义为静态类

(6)不能声明一个静态类的变量,比如静态类Person p;

静态构造函数:非静态类也可以有静态构造函数

静态类的成员第一次被访问之前就会执行静态构造函数

静态构造函数只被执行一次

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网