【2020-01-08】类和对象

类是一种数据结构,可以在一个单元中将状态(字段)和操作(方法和其他函数成员)结合起来。类为动态创建的类实例(亦称为:对象)提供了定义

类支持继承和多形性,即派生类可以扩展和专门针对基类的机制

新类使用类声明进行创建。类声明的开头是标头,指定了类的特性和修饰符、类名、基类(若指定)以及类实现的接口。标头后面是类主体,由在分隔符{和}内编写的成员声明列表组成

一、成员

类成员要么是静态成员,要么是实例成员。静态成员属于类,而实例成员属于对象

下面是类中可包含的成员类型

1、常量 

与类相关联的常量值

2、字段

类的常量

3、方法

类可以执行的计算和操作

4、属性

与读取和写入类的已命名属性相关联的操作

5、索引器

与将类实例编入索引(像处理数组一样)相关联的操作

6、事件

类可以生成的通知

7、运算符

类支持的转换和表达式元素符

8、构造函数

初始化类实例或类本身所需的操作

9、终结器

永久放弃类实例前要执行的操作

10、类型

类声明的嵌套类型

三、可访问性

 每个类成员都有关联的可访问性,用于控制能够访问成员的程序文本区域,可访问性有六种可能的形式。

1、public

访问不受限

2、protected

只能在此类或其派生类中访问 (可跨不同的程序集)

3、internal

只能在当前程序集中访问(.exe  .dll等)   

4、protected internal

在此类和其派生类中可以访问  在同一程序集中的所有类中访问

5、private

只能在此类中访问

5、private protected

只能在同一程序集中 的类或者其派生类中访问

【说明】:

类的默认访问级别是  internal

方法的默认访问级别是 private

四、类型参数

类定义可能会按如下方式指定一组类型参数:在类名后面用尖括号括住 类型参数名称列表。然后,可以在类声明的主体中使用类型参数来定义类成员

包含类型自变量的泛型类型,被称为构造泛型类型 (such as  Pair<int, string>)

五、基类

类声明可能会按如下方式指定基类:在类名和类型参数后面编写冒号和基类名。省略基类规范与从object类型派生相同。

 类继承其基类的成员。继承是指隐式包含其基类的所有成员的类,实例和静态构造函数以及基类的终结器除外。派生类可以继承的类添加新成员z,但无法删除成员的定义。

可以将类类型隐式转换为其他任意基类类型,因此类类型的变量可以引用相应类的实例或任意派生类的实例。例如:

 六、字段

字段是与类或类实例相关联的变量

使用静态修饰符声明的字段定义的是静态字段。静态字段只指明一个存储位置。无论创建多少个类实例,永远只有一个静态字段副本

不使用静态修饰符声明的字段定义的是实例字段。每个类实例均包含相应类的所有实例字段的单独副本

可以用readonly修饰符声明只读字段。只能在字段声明期间或在同一个类的构造函数中向readonly字段赋值

 七、方法

方法是实现对象或类可执行的计算或操作的成员。静态方法是通过类进行访问。实例方法是通过类实例进行访问

方法可能具有参数列表,用于表示传递给方法的值或变量引用;并具有返回类型,用于指定方法计算并返回的值的类型。

如果方法未返回值,则其返回类型为void

方法可能也包含一组类型参数,必须在调用方法时指定类型自变量,这一点与类型一样。与类型不同的是,通常可以根据方法调用的自变量推断出类型自变量,无需显示指定

在声明方法的类中,方法的签名必须是唯一的。方法签名包含方法名称,类型参数数量以及其参数的数量,修饰符和类型。方法签名不包含返回类型

 八、参数

参数用于将值或变量引用传递给方法。方法参数从调用方法时指定的自变量中获取其实际值。有四类参数:值参数,引用参数,输出参数,参数数组

1、值参数用于传递输入自变量。值参数对应于局部变量,从为其传递的自变量中获取初始值。修改值参数不会影响为其传递的自变量

2、可以指定默认值,从而省略相应的自变量,这样值参数就是可选的

3、引用参数用于按引用传递自变量。为引用参数传递的自变量必须是具有明确值的变量,并且在方法执行期间,引用参数指明的存储位置与自变量相同。引用参数使用ref 修饰符进行声明

 4、输出参数用于按引用传递自变量。输出参数与引用参数类似,不同之处在于,不要求向调用方法提供的自变量显示赋值。输出参数使用out 修饰符进行声明。

 5、参数数组 允许向方法传递数量不定的自变量。参数数组使用params修饰符进行声明。参数数组只能是方法的最后一个参数,且参数数组的类型必须是一维数组类型

在使用参数数组的方法中,参数数组的行为与数组类型的常规参数完全相同。不过在调用包含参数数组的方法时,要么可以传递参数数组的元素类型的任意数量自变量。在后一种情况中,数组实例会自动创建,并初始化为包含给定的自变量

 九、方法主体和局部变量

方法主体指定了在调用方法时执行的语句

方法主体可以声明特定于方法调用的变量,此类变量称为局部变量。局部变量声明指定了类型名称以及可能的初始值。

C#要求必须先给变量赋值,才可以获取其值

十、静态和实例方法

使用静态修饰符声明的方法是静态方法。静态方法不对特定的实例起作用,只能直接访问静态成员

不使用静态修饰符声明的方法是实例方法,实例方法对特定的实例起作用,并能够访问静态和实例成员

 十一、虚方法、重写方法和抽象方法

1、如果实例方法声明中有virtual 修饰符,可以将实例方法称为“虚方法”。如果没有virtual 修饰符,可以将实例方法称为“非虚方法”

2、如果要重写基类中的一个方法,除了要加override修饰符,还要保证此方法在基类中有virtual修饰符

3、调用虚方法时,为其调用方法的实例的运行时类型决定了要调用的实际方法实现代码。(相当于typescript中的类 --- 执行方法取决于类实例的类型,而不是类类型)

 

4、调用非虚方法时,实例的编译时类型是决定性因素

5、可以在派生类中重写虚方法。如果实例方法声明中有override 修饰符,那么实例方法可以重写签名相同的继承虚方法。虚方法声明是用于引入新方法,重写方法声明通过提供相应方法的新实现代码,专门针对现有的继承虚方法 

6、抽象方法是没有实现代码的虚方法。抽象方法使用abstract 修饰符进行声明,只能在同样声明了abstract的类中使用。必须在所有非抽象派生类中重写抽象方法

 抽象类是没有实例的,只能创建抽象类的派生类的实例

派生类中若要重写抽象基类的方法,也需要加上override修饰符

十二、方法重载

同一类中有多个同名的方法,只要这些方法具有唯一的签名即可

十三、其他函数成员

包含可执行代码的成员统称为类函数成员。包含:方法、构造函数、属性、索引器、事件、运算符、和终结器

1、构造函数

没有static修饰符的构造函数是实例构造函数 -不能被继承

有static修饰符的构造函数称为 静态构造函数

2、属性

属性与字段不同的是,属性不指明存储位置。相反,属性包含访问器,用于指定在读取或写入属性值时要执行的语句

类似于字段和方法,C#支持实例属性和静态属性。静态属性使用静态修饰符进行声明,而实例属性则不使用静态修饰符进行声明。

属性的访问器可以是虚的。如果属性声明包含virtual , abstract, override修饰符,则适用于属性的访问器

3、索引器

借助索引器成员,可以将对象编入索引(像处理数组一样)。索引器的声明方式与属性类似,不同之处在于,索引器成员名称格式为this后跟在分隔符[ 和 ]内写入的参数列表。

这些参数在索引器的访问器中可用。类似于属性,索引器分为读写,只读,只写索引器,且索引器的访问器可以是虚的

 索引器可以进行重载,也就是说,类可以声明多个索引器,只要其参数的数量或类型不同即可

4、事件

借助事件成员,类或对象可以提供通知,事件的声明方式与字段类似,不同之处在于,事件声明包括事件关键字,且类型必须是委托类型

在声明事件成员的类中,事件的行为与委托类型的字段完全相同(前提是事件不是抽象的,且不声明访问器)

字段存储对委托的引用,委托表示已添加到事件的事件处理程序中,如果没有任何事件处理程序,则字段为null

5、运算符

6、终结器

终结器是实现完成类实例所需的操作的成员,终结器既不能包含参数和可访问性修饰符,也不能进行显示调用。实例的终结器在垃圾回收期间自动调用

垃圾回收器在决定何时收集对象和运行终结器时有很大自由度。具体来说,终结器的调用时间有不确定性,可以在任意线程上执行终结器。 因为这样或那样的原因,只有在没有其他可行的解决方案时,类才能实现终结器。

 

猜你喜欢

转载自www.cnblogs.com/QQ-lala/p/12168426.html
今日推荐