您好,欢迎访问三七文档
10.类类是一种数据结构,它可以包含数据成员(常数和字段)、函数成员(方法、属性、事件、索引器、运算符、实例构造函数、静态构造函数和析构函数)以及嵌套类型。类类型支持继承,继承是一种机制,它使派生类可以对基类进行扩展和专用化。10.1类声明类声明是一种类型声明(第9.5节),它用于声明一个新类。class-declaration:(类声明:)attributesoptclass-modifiersoptclassidentifierclass-baseoptclass-body;opt(属性可选类修饰符可选class标识符类基可选类体;可选)类声明的组成方式如下:先是一组属性(第17节)(可选),后跟一组类修饰符(第10.1.1节)(可选),然后是关键字class和一个用来命名该类的标识符,接着是一个类基规范(第10.1.2节)(可选),最后还可添加一个分号(第10.1.3节)(可选)。10.1.1类修饰符类声明可以根据需要包含一个类修饰符序列:class-modifiers:(类修饰符:)class-modifier(类修饰符)class-modifiersclass-modifier(类修饰符类修饰符)class-modifier:(类修饰符:)newpublicprotectedinternalprivateabstractsealed同一修饰符在一个类声明中多次出现是编译时错误。new修饰符适用于嵌套类。它表示所修饰的类会把继承下来的同名成员隐藏起来,如第10.2.2节中所描述。如果new修饰符出现在一个类声明中,而该声明又不是一个嵌套类声明,则导致一个编译时错误。public、protected、internal和private修饰符控制类的可访问性。根据类声明出现处的上下文,这些修饰符中,有些可能不允许使用(第3.5.1节)。以下几节对abstract和sealed修饰符进行了讨论。10.1.2类基规范类声明可以包含一个类基规范,它定义该类的直接基类和由该类实现的接口(错误!未找到引用源。)。class-base:(类基:):class-type(:类类型):interface-type-list(:接口类型列表):class-type,interface-type-list(:类类型,接口类型列表)interface-type-list:(接口类型列表:)interface-type(接口类型)interface-type-list,interface-type(接口类型列表,接口类型)10.1.3类体一个类的类体用于定义该类的成员。class-body:(类体:){class-member-declarationsopt}({类成员声明可选})10.2类成员一个类的成员由两部分组成:由它的类成员声明引入的成员;从它的直接基类继承来的成员。class-member-declarations:(类成员声明:)class-member-declaration(类成员声明)class-member-declarationsclass-member-declaration(类成员声明类成员声明)class-member-declaration:(类成员声明:)constant-declaration(常数声明)field-declaration(字段声明)method-declaration(方法声明)property-declaration(属性声明)event-declaration(事件声明)indexer-declaration(索引器声明)operator-declaration(运算符声明)constructor-declaration(构造函数声明)destructor-declaration(析构函数声明)static-constructor-declaration(静态构造函数声明)type-declaration(类型声明)一个类的成员分为下列几种类别:常数,表示与该类相关联的常数值(第10.3节)。字段,即该类的变量(第10.4节)。方法,用于实现可由该类执行的计算和操作(第10.5节)。属性,用于定义一些命名特性,通过它来读取和写入相关的特性(第10.6节)。事件,用于定义可由该类生成的通知(第10.7节)。索引器,使该类的实例可按与数组相同的(语法)方式进行索引(第10.8节)。运算符,用于定义表达式运算符,通过它对该类的实例进行运算(第10.9节)。实例构造函数,用于规定在初始化该类的实例时需要做些什么(第10.10节)。析构函数,用于规定在永久地放弃该类的一个实例之前需要做些什么(第10.12节)。静态构造函数,用于规定在初始化该类自身时需要做些什么(第10.11节)。类型,用于表示一些类型,它们是该类的局部类型(第9.5节)。可以包含可执行代码的成员统称为该类的函数成员。一个类的函数成员包括:方法、属性、事件、索引器、运算符、实例构造函数、析构函数和静态构造函数。一个类声明将创建一个新的声明空间(第3.3节),而直接包含在该类声明内的类成员声明将在此声明空间中引入新成员。下列规则适用于类成员声明:实例构造函数、静态构造函数和析构函数必须具有与直接封闭它们的类相同的名称。所有其他成员的名称必须与该类的名称不同。常数、字段、属性、事件或类型的名称必须不同于在同一个类中声明的所有其他成员的名称。方法的名称必须不同于在同一个类中声明的所有其他非方法的名称。此外,方法的签名(第3.6节)必须不同于在同一个类中声明的所有其他方法的签名。实例构造函数的签名必须不同于在同一个类中声明的所有其他实例构造函数的签名。索引器的签名必须不同于在同一个类中声明的所有其他索引器的签名。运算符的签名必须不同于在同一个类中声明的所有其他运算符的签名。类的继承成员(第10.2.1节)不是类的声明空间的组成部分。因此,一个派生类可以使用与所继承的成员相同的名称或签名来声明自已的新成员(这同时也隐藏了被继承的同名成员)。10.1.2.1基类当类基中包含一个类类型时,它表示该类就是所声明的类的直接基类。如果一个类声明中没有类基,或所含的类基只列出接口类型,则假定直接基类就是object。一个类会从它的直接基类继承成员,如第10.2.1节中所描述。在下面的示例中classA{}classB:A{}称类A为类B的直接基类,而称B是从A派生的。由于A没有显式地指定直接基类,它的直接基类隐含地为object。一个类类型的直接基类必须至少与该类类型本身具有同样的可访问性(第3.5.4节)。例如,试图从private或internal类派生一个public类,会导致一个编译时错误。一个类类型的直接基类不能是任何下列类型:System.Array、System.Delegate、System.Enum或System.ValueType。一个类的基类包括它的直接基类以及该直接基类的基类。换句话说,基类集是直接基类关系的传递闭包。在上面的例子中,B的基类就包括A和object。除了类object,每个类有且只有一个直接基类。object类没有任何直接基类,并且是所有其他类的终极基类。当类B从类A派生时,A依赖于B是编译时错误。类直接依赖于它的直接基类(如果有的话),并且还直接依赖于它直接嵌套于其中的类(如果有的话)。从上述定义可以推出:一个类所依赖的类的完备集就是此“直接依赖于”关系的传递闭包。示例classA:B{}classB:C{}classC:A{}是错误的,因为这些类之间循环依赖。同样,示例classA:B.C{}classB:A{publicclassC{}}也会导致一个编译时错误,原因是A依赖于B.C(它的直接基类),B.C依赖于B(它的直接封闭类),而B又循环地依赖于A。请注意,一个类不依赖于嵌套在它内部的类。在下面的示例中classA{classB:A{}}B依赖于A(原因是A既是它的直接基类又是它的直接封闭类),但是A不依赖于B(因为B既不是A的基类也不是A的封闭类)。因此,此示例是有效的。不能从一个sealed类派生出别的类。在下面的示例中sealedclassA{}classB:A{}//Error,cannotderivefromasealedclass类B发生错误,因为它试图从sealed类A派生。10.2.2new修饰符类成员声明中可以使用与一个被继承的成员相同的名称或签名来声明一个成员。发生这种情况时,就称该派生类成员隐藏了基类成员。隐藏一个继承的成员不算是错误,但这确实会导致编译器发出警告。若要取消此警告,派生类成员的声明中可以包含一个new修饰符,表示派生成员是有意隐藏基成员的。第3.7.1.2节中对该主题进行了进一步讨论。如果在一个不会隐藏继承成员的声明中使用了new修饰符,将为此发出警告。通过移除new修饰符可取消显示此警告。10.2.3访问修饰符类成员声明中可以使用下列五种可能的声明可访问性(第3.5.1节)中的任何一种:public、protectedinternal、protected、internal或private。除protectedinternal组合外,指定一个以上的访问修饰符是编译时错误。当类成员声明不包含任何访问修饰符时,假定为private。10.2.4构成类型在成员声明中所使用的类型称为成员的构成类型。可能的构成类型包括常数、字段、属性、事件或索引器类型,方法或运算符的返回类型,以及方法、索引器、运算符和实例构造函数的参数类型。一个成员的构成类型必须至少具有与该成员本身相同的可访问性(第3.5.4节)。10.2.5静态和实例成员类的成员或者是静态成员,或者是实例成员。一般说来,可以这样来理解:静态成员属于类,而实例成员属于对象(类的实例)。当字段、方法、属性、事件、运算符和构造函数声明中含有static修饰符时,它声明静态成员。此外,常数或类型声明会隐式地声明静态成员。静态成员具有下列特征:在E.M形式的成员访问(第7.5.4节)中引用静态成员M时,E必须表示含有M的那个类型本身。E若表示一个实例,则会导致一个编译时错误。一个静态字段只标识一个存储位置。对一个类无论创建了多少个实例,它的静态字段永远都只有一个副本。静态函数成员(方法、属性、事件、运算符或构造函数)不能作用于具体的实例,在这类函数成员中引用this会导致一个编译时错误。当字段、方法、属性、事件、索引器、构造函数或析构函数的声明中不包含static修饰符时,它声明实例成员。(实例成员有时称为非静态成员。)实例成员具有以下特点:在E.M形式的成员访问(第7.5.4节)中引用实例成员M时,E必须表示某个含有M的类型的一个实例。E若表示类型本身,则会导致一个编译时错误。类的每个实例分别包含一组该类的所有实例字段。实例函数成员(方法、属性、索引器、实例构造函数或析构函数)作用于类的特定实例,此实例可以用this访问(第7.5.7节)。下列示例阐释访问静态和实例成员的规则:classTest{intx;staticinty;voidF(){x=1;//Ok,sameasthis.x=1y=1;//Ok,sameasTest.y=1}staticvoidG(){x=1;//Error,cannotaccessthis.xy=1;//Ok,sameasTest.y=1}staticvoidMain(){Testt=newTest();t.x=1;//Okt.y=1;//Error,cannotaccessstaticmemberthroughinstanceTest.x=1;//Error,cannotaccessinstancememberthroughtypeTest.y=1;//Ok}}F方法显示,在实例函数成员中,简单名称(第7.5.2节)既可用于访问实例成员也可用于访问静态成员。G方法显示,在静态函数成员中,通过简单名称访问实例成员是编译时错误。Main方法显示
本文标题:C第10章
链接地址:https://www.777doc.com/doc-3102876 .html