·方法 ·属性 ·索引器 ·事件
类是对象概念在面向对象编程语言中的反映,是相同对象的集合。类描述了一系列在概念上有相同含义的对象,并为这些对象统一定义了编程语言上的属性和方法。
类修饰符 class 类名 { }
例如: public class Car { public int number; //编号
public string color; //颜色
private string brand; //厂家 }
构造函数和析构函数是类中比较特殊的两种成员函数,主要用来对对象进行初始化和回收对象资源。一般来说,对象的生命周期从构造函数开始,以析构函数结束。如果一个类含有构造函数,在实例化该类的对象时就会调用,如果含有析构函数,则会在销毁对象时调用。构造函数的名字和类名相同,析构函数和构造函数的名字相同,但析构函数要在名字前加一个波浪号(~)。当退出含有该对象的成员时,析构函数将自动释放这个对象所占用的内存空间。
(1)构造函数:构造函数是在创建给定类型的对象时执行的类方法。构造函数具有与类相同的名称,它通常初始化新对象的数据成员。
(2)析构函数:析构函数是以类名加~来命名的。.NET Framework类库有垃圾回收功能,当某个类的实例被认为是不再有效,并符合析构条件时,.NET Framework类库的垃圾回收功能就会调用该类的析构函数实现垃圾回收。
对象是具有数据、行为和标识的编程结构,它是面向对象应用程序的一个组成部分,这个组成部分封装了部分应用程序,这部分程序可以是一个过程、一些数据或一些更抽象的实体。 对象包含变量成员和方法类型,它所包含的变量组成了存储在对象中的数据,而其包含的方法可以访问对象的变量。略为复杂的对象可能不包含任何数据,而只包含方法,并使用方法表示一个过程。 C#中的对象是把类实例化,这表示创建类的一个实例,“类的实例”和对象表示相同的含义,但需要注意的是,“类”和“对象”是完全不同的概念。
类是一种抽象的数据类型,但是其抽象的程度可能不同,而对象就是一个类的实例。类是具有相同或相似结构、操作和约束规则的对象组成的集合,而对象是某一类的具体化实例,每一个类都是具有某些共同特征的对象的抽象。
三、结构体(struct)
public struct AddressBook
//字段、属性、方法、事件
对于类而言,两个变量指向同一个对象的情况是存在的,因此对这样两个变量中的任意一个进行操作,起结果必然会影响另外一个,因为它们指向的是同一个对象。
结构是值类型,直接包含它自己的数据,每个结构都保存自己的一份数据,修改每一个结构的数据都不会对其他结构的数据造成影响。
如果从结构中创建一个对象,并将该对象赋给某个变量,则该变量包含结构的全部值。复制类型为结构的变量时,将同时复制该结构所持有的所有数据。由于结构不是引用类型,因此结构类型的变量不能被赋予null值。
将一个结构变量赋值给另一个结构变量,就是把数据从一个结构复制到另一个结构。而类则不同,在类的变量之间,复制的是引用,而不是类数据。因此当数据比较大的时候,这种数据复制机制会带来较大的开销。
结构类型可以有实例构造函数和静态构造函数,但不能有析构函数。
(1)实例构造函数
结构类型都有一个预定义的,没有参数的构造函数,这点与类是一样的。
注意如果没有使用new运算符,是不可以使用数据成员的值(除非已显示地设置了该数据成员的值)和调用函数成员的(除非所有数据成员均已经被赋值)。
和类一样,结构类型也可以有静态构造函数,静态构造函数用于初始化静态数据成员。静态构造函数有如下特点:
1、静态构造函数不能有访问修饰符和参数;
2、静态构造函数不能访问实例成员;
3、静态构造函数无法直接进行调用;
结构和类的静态构造函数的触发规则不同,类的静态构造函数是在创建第一个实例或引用任何静态成员之前自动调用的,而结构的静态构造函数在以下情况调用:
2、调用结构的方法或访问结构的静态数据成员(无论是读取还是赋值,访问实例数据成员不会触发CLR自动调用静态的构造函数)。
1、结构类型总是隐式密封的,因此在定义结构时不能使用sealed和abstract关键字;
2、因为结构不能作为基类,结构的成员不能使用如下访问修饰符:protected和protected,internal;
结构是值类型,因此当它被转换为object类型时,或者它所实现的接口类型的时候,就会执行装箱操作;同样,当执行相反操作的时候,就会执行
拆箱操作。
是否有析构函数 无 有 可否从类派生 否 可以 可否实现接口 可以 可以 实例化时在栈还是在堆分配内存 栈 堆,栈中保存引用 该类型的变量可否被赋值为null 否 可以 可否定义私有的无参构造函数 否 可以 是否总有一个默认的无参构造函数 是 否
无论结构使用预定义的、无参数的构造函数,还是使用用户定义的、有参数的构造函数进行初始化,都会初始化结构的数据成员。不过预定义的,无参的会将数值型初始化为默认值,引用类型初始化为null;而用户自定义的初始化策略对个成员进行初始化。因此结构类型的数据成员不允许在声明是显式初始化。
因为结构是值类型,因此在为结构分配内存,或者当结构超出了作用域被删除时,性能会非常好,因为他们将内联或者保存在堆栈中。当把一个结构类型的变量赋值给另一个结构时,对性能的影响取决于结构的大小,如果结构的数据成员非常多而且复杂,就会造成损失,接下来使用一段代码来说明这个问题。
1、当堆栈的空间很有限,且有大量的逻辑对象时,创建类要比创建结构好一些。
3、在表现抽象和多级别的对象层次时,类是最好的选择,因为结构不支持继承。
4、大多数情况下,目标类型只是含有一些数据,或者以数据为主。
四、属性(property)
属性访问标记可以为public,private,protected,internal,protected internal,因为访问器的访问限制必须比属性的访问限制更加严格,所以能对接口或者显式的接口使用访问器的访问限制必须比属性的访问限制更加严格,所以能对接口或者显式的接口使用访问修饰符,因为接口里里面所有的默认是public的;同时具有get,set访问器时,才允许使用访问修饰符,并且只能有一个使用;如果属性有override修饰的时候,访问器修饰符必须与被重写的匹配。访问器的可访问级别必须比属性的可访问级别更加严格
委托是面向对象编程的基本思想之一,就是将具有共同特征的某一类具体对象抽象为类。
delegate void MyDel(int x);
(1) 以deleagate关键字开头。
(2)返回类型+委托类型名+参数列表。
(1) 使用new运算符
new运算符的操作数的组成如下:
委托类型名
一组圆括号,其中包含作为调用列表中的第一个成员的方法的名字。方法可以实例方法或静态方法。
(2)使用快捷语法
快键语法,它仅由方法说明符构成。之所以能这样,是因为在方法名称
和其相应的委托类型之间有隐式转换。
由于委托是引用类型,我们可以通过给它赋值来改变包含在委托变量中的方法地址引用。旧的引用会被垃圾回收器回收。
委托可以使用额外的运算符来组合。这个运算最终会创建一个新的委托,其调用列表是两个操作数的委托调用列表的副本的连接。
可以使用+=运算符,为委托新增方法。
同样可以使用-=运算符,为委托移除方法。
委托调用跟方法调用类似。委托调用后,调用列表的每个方法将会被执行。
在调用委托前,应判断委托是否为空。调用空委托会抛出异常。
基本结构:
deleage( 参数 ) { 语句块 }
Lambda表达式主要用来简化匿名方法的语法。在匿名方法中,delegate关键字有点多余,因为编译器已经知道我们将方法赋值给委托。通过几个简单步骤,我们就可以将匿名方法转换为Lambda表达式:
删除delegate关键字
在参数列表和匿名方法主体之间防Lambda运算符=>。Lambda运算符读作"goes to"。
六、事件(event)
C#中的事件处理实际上是一种具有特殊签名的delegate,象下面这个样子:public delegate void MyEventHandler
(object sender, MyEventArgs e); 其中的两个参数,sender代表事件发送者,e是事件参数类。 MyEventArgs类用来包含与事件相关的数据,所有的事件参数
(1)、定义delegate对象类型,它有两个参数,第一个参数是事件发送者对象,第二个参数是事件参数类对象。