收藏 分享(赏)

第二章 C#程序设计基础.ppt

上传人:j35w19 文档编号:8699491 上传时间:2019-07-08 格式:PPT 页数:102 大小:161.50KB
下载 相关 举报
第二章  C#程序设计基础.ppt_第1页
第1页 / 共102页
第二章  C#程序设计基础.ppt_第2页
第2页 / 共102页
第二章  C#程序设计基础.ppt_第3页
第3页 / 共102页
第二章  C#程序设计基础.ppt_第4页
第4页 / 共102页
第二章  C#程序设计基础.ppt_第5页
第5页 / 共102页
点击查看更多>>
资源描述

1、第二章 C#程序设计基础,第二章 C#程序设计基础,2.1 C#语法介绍 2.2 值类型 2.3 引用类型 2.4 异常处理 2.5 C#面向对象的编程 2.6 装箱与拆箱 本章小结,2.1.1 C#程序的基本结构,一个C#程序可以由一个或多个文件组成。它的程序是阶层式的结构。 C#程序的基本结构包括:命名空间声明、类声明、“Main()”方法声明和语句。下面讲解一个简单实例。 例2.1 一个简单实例,此程序只有一个可执行语句,程序运行时在屏幕上输出:C#语言的基本结构!,2.1.1 C#程序的基本结构,using System; / 使用System命名空间声明 namespace MyNa

2、me1 / 声明用户命名空间MyName1 class Myclass / 声明Myclass类public static void Main() / 声明Main方法,此处是程序的入口Console.WriteLine(“C#语言的基本结构!“);/* 从此开始多行整块注释,注释内容将被编译器忽略。 */ ,2.1.1 C#程序的基本结构,在C#的基本结构中: 类和方法以“”开始,以“”结束; 一个C#程序必须有唯一的Main()方法; 所有的语句都以分号“;”结束; 程序可以加注释,有两种方法:一种是“/”表示单行注释,表示从该注释符号开始到该行结束都是注释;另一种是以“/*”开始,以“*

3、/”结束的多行注释。,2.1.1 C#程序的基本结构,在控制平台编译和运行源程序,需要计算机必须安装.NET Framework SDK。此案例中,调用了Console的WriteLine()方法在屏幕上输出一行提示信息。可以使用一个文本编辑器编写这段代码,将它存为cjg.cs文件。 .NET Framework SDK内置了C#编译器。打开“Visual Studio.NET 2003命令提示”命令窗口。转到保存文件所在目录,在命令行输入: csc cjg.cs,编译成功,就会得到可执行文件cjg.exe。在命令行输入执行文件命令:cjg回车,就会显示输出结果:C#语言的基本结构!,2.1.

4、2 变量与常量,1. 变量 变量是指在程序运行过程中,其值可以发生变化的量,通常用来保存程序运行过程中的输入数据、计算获得的中间结果和最终结果。每个变量都有一种类型来确定什么样的数据可以存储在该变量中。 C#是一种的安全语言,编译器会检查变量和它所存储的数据类型是否一致,C#中所有变量必须“先声明后引用”,变量的声明语句的一般形式为:附加属性 修饰符 类型名 变量声明符列表;,2.1.2 变量与常量,说明: 1)附加属性:附加声明信息; 2)修饰符:允许的修饰符有new和pulic protected internal private 有效组合; 3)变量声明符:变量名表示符,变量名必须是合法

5、的标示符。 4)变量声明符列表:以逗号分隔的若干个变量声明符; 在声明变量时可以用变量初始化设定项给它赋初始值,也可以在声明时不初始化。C#的编译器要对所有的变量作用明确赋值检查,如果检查出未初始化的某变量,在使用变量之前必须对它赋值,如果不赋值,编译器会发出错误警告。,2.1.2 变量与常量,C#语言中共有七种变量:静态变量、非静态变量、数组元素、值参数、引用参数、输出参数和局部变量。 1)静态变量 在类中使用static修饰符声明的字段成为静态变量,静态变量与所属的类生命期相同。静态变量被视为初始已赋值 ,初始值是变量类型默认值。 2)非静态变量 没有使用static修饰符声明的变量。 在

6、类中直接声明的不带static修饰符声明的变量成为非静态变量。 在结构中声明的不带static修饰符的变量也是非静态变量。,2.1.2 变量与常量,3)数组元素 数组的一个元素当一个数组实例产生时存在,当没有对数组实例进行引用时消失。数组元属被视为初始已赋值,数组元素的初始值是该变量类型默认值。 4)值参数 没有用ref或out限定符声明的参数叫值参数。当调用该值参数所属的成员函数时,才产生该值参数,调用完毕后,值参数消失。 5)引用参数 一个用ref限定符声明的参数叫引用参数,一个引用参数不产生新的存储地址,相反,它表示的存储地址与函数成员调用中的变量相同,因此,引用变量的值与所传递的变量相

7、同。,2.1.2 变量与常量,6)输出参数 用out限定符声明的变量叫输出参数。输出参数不产生一个新的存储地址,相反,它表示的存储地址与函数成员调用中的变量相同,因此输出参数的值与所传递的变量相同。 7)局部变量 局部变量是通过局部变量声明语句定义的,该声明可以出现在块、for语句、foreach语句、switch语句或using语句中。一个局部变量不会自动被初始化,因此没有默认值,为了对明确地赋值进行校验,一个局部变量被认为是初始未被赋值过。如果局部变量声明包括变量初始值设定项,则该局部变量被视为在它的整个有效范围内已明确赋值。在局部变量声明语句之前引用该局部变量将会导致编译时错误。,2.1

8、.2 变量与常量,2. 常量 常量是用来表示常数的类成员,它有一个名称标识符。一个常量在使用之前必须用常量声明语句来明确它的类型和值。常量声明语句的形式:附加属性 修饰符 const 常量类型名 声明式列表; 说明: 附加属性:附加声明信息。 修饰符:允许的修饰符有 new、pulic、protected、internal和private的有效组合。 常数类型名:byte、char、short、int、long、float、double、decimal、bool、string。 声明式列表:以逗号分隔的声明式列表。 声明式:常量名=常量表达式,2.1.2 变量与常量,一条声明多个常量的常量声明

9、与声明单个常量的多个声明,当它们有相同的附加属性、修饰符和类型时相互等价。例如: class A public const double X=1.0 , Y=2.0 , Z=3.0; 等同于 class A public const double X=1.0; public const double Y=2.0; public const double Z=3.0; ,2.1.3 表达式,表达式是由操作符(运算符)和操作数组成的一组有序的计算式。操作符表示对于操作数进行运算。 表达式的分类: 表达式按操作符分类,通常由算术操作符、位操作符构成算术表达式;由操作运算符构成赋值表达式;由关系操作符

10、构成关系表达式;由逻辑操作符构成逻辑表达式;由特殊操作符构成的表达式可以按其最终结果类型分类。 一个表达式可以由以下元素组成:值、变量、命名空间、类型、方法、属性存取、事件存取、索引存取等多种元素。,2.1.4 C#操作符,运算就是对数据或变量进行加工处理的过程。描述各种不同运算的符号称为操作符或运算符。C#提供了丰富的操作符,见书中表2.1。,2.1.4 C#操作符,按所操作对象的数目划分,操作符可分为三类。 一元(单目)操作符 带有一个运算对象并用到前缀表达式或后缀表达式。例如:X , X+ 二元操作符 带有二个运算对象并用到前缀表达式或后缀表达式。例如:X+Y,X-Y,X/5 三元操作符

11、 只有一种三元操作符“?”,称为三元条件运算符。三元操作符带有3个运算对象,运算符中的两个符号插在三个操作数中间。例如:表达式(y 7 ? a : b),其中“?”代表一个判断, “:”则将判断后的两种取值分开,此例表示如果y8为真则取a的值,否则取b的值。,2.1.5 C#控制语句,C#直接借用C和C+的大部分语句,并对之作了一些改动和调整。C#的语句包括:基本语句、标记语句、声明语句、选择语句、迭代语句。下面介绍几种常见语句:,2.1.5 C#控制语句,1. if语句 if语句用于在程序中有条件地执行一段代码,语法形式如下: if (expression ) statement; /当ex

12、pression为真时执行statement语句序列. 说明:表达式值为“真”,执行statement语句内容。 注意:表达式必须用圆括号括起来。,2.1.5 C#控制语句,2. if-else语句 if-else语句用于程序根据一个特定表达式的值执行两种单独的动作。语法形式如下: if (expression ) statement1; /当expression为真时执行statement1语句序列. else statement2; /当expression为真时执行statement1语句序列. ,2.1.5 C#控制语句,3. switch语句 switch语句是多选择控制语句,根据与

13、指定的表达式相关的值来执行不同的语句,如果没有与之匹配的值,执行一个默认语句。 switch语句通过将控制传递给其体内的某个case子句来处理多个选择。其语法形式如下: switch (表达式) case 标号:内嵌语句列表;default :内嵌语句列表;,2.1.5 C#控制语句,switch语句的功能是:将控制转到与“表达式”值匹配的“常量表达式”所对应的case子句。switch语句可包含任意数量的case子句,但同一switch语句中的两个case子句的“常量表达式”不能具有相同的值。如果“表达式”的值与任何“常量表达式”都不匹配,则控制转到default标号后面的内嵌语句列表。如果

14、没有default标号,则控制传递到switch之后的下一条语句。,2.1.5 C#控制语句,例2.2 根据输入的字符分不同情况输出对应的字符串 using System; class SwitchTest public static void Main()Console.WriteLine(“Size:1=Small 2=Medium 3=Large“);Console.Write(“Please enter your selection:“);string s=Console.ReadLine();,2.1.5 C#控制语句,switch(s)case “0“:goto case “1“;

15、case “1“:Console.WriteLine(“Small size.“);break;case “2“:Console.WriteLine(“Medium size.“);break;case “3“:Console.WriteLine(“Large size.“);break;default:Console.WriteLine(“Invalid selection.“);break;Console.WriteLine(“Thanke you for your business.“);,2.1.5 C#控制语句,运行输出结果: Size: 1= Small 2=Medium 3=La

16、rge Please enter you selection: 输入选择:1、2或3 Please enter you selection:2 回车 Medium size Tank you for your business.,2.1.5 C#控制语句,4. while语句 while语句是一种“预测试”的循环。是当型循环语句,它的形式为: while (expression) statement; ,2.1.5 C#控制语句,5. do-while语句 do-while语句是一种“后测试”的循环。在循环体中先执行一次再判断表达式的值,所以do-while循环语句总能保证循环体被执行一次。它

17、是直到型循环。它的形式为: do statement; while (expression);,2.1.5 C#控制语句,6. for语句 for语句首先计算初始化表达式,当判断条件成立时,反复执行循环体,并重新计算循环判断表达式。是一种计数的循环。它的形式为: for(expression1;expreeion2;expression3) statement;.,2.1.5 C#控制语句,例2.3 for循环实例 using System; class Test static void Main() for(int i=0;i3;i+)Console.WriteLine(i); 运行输出结果

18、: 0 1 2,2.1.5 C#控制语句,7. foreach语句 foreach语句是C#特有的一种循环,foreach语句枚举集合中的每一个元素,并为集合中的每个执行一次语句。它的形式为: foreach( type identifier in expression ) embedded-statement,2.1.5 C#控制语句,说明: type:类型名,指定其后变量类型名。 identifier:变量名,表示集合或数组元素的迭代变量名。 expression:表达式,对象集合或数组表达式。其元素的类型必须可以转换为类型名所指定的类型。 embedded-statement:循环体,要

19、执行的嵌入语句或语句块。 Foreach语句为数组或集合中的每个元素执行一遍循环体,循环体中用指定的变量代表集合元素或数组元素。,返回,2.2 值类型,C#是个强类型的安全语言,编译器要对所有变量的数据类型作严格的检查,保证存储在变量中的每个数值与变量类型一致。 C#的数据类型分为两大类:值类型(value-type)和引用类型(reference-type) 1)值类型包括简单类型、枚举类型和结构类型 2)引用类型包括类类型、接口类型、数组类型、委托类型 C#语言的数据类型是统一的,所以任何类型的值都可以被当作对象,C#语言的任何类型都是直接或间接地从object类型派生来的,object是

20、所有类型的基类型。,2.2 值类型,值类型包括简单类型、结构类型和枚举类型。还可以进一步细分:,2.2.1 整型,C#语言中共有九种整型: sbyte、byte、short、ushort、char、int、uint、long、ulong。这九种整数所占存储单元和表示数的范围(取值范围)各不相同。,2.2.2 布尔类型,布尔类型表示逻辑量,可能的值是true和false。在C+语言中,布尔类型的值可转换为int类型的值;false等效于零值,而true等效非零值。在C#中为了增加安全性这种方法已经被废弃,用整数值表示逻辑值是非法的。C#只能用true和false表示逻辑运算中的“真”和“假”,不

21、能进行布尔类型与其它类型之间的相互转换。,2.2.3 浮点型,C#支持两种浮点类型:float和double,它们分别是32位的单精度浮点数和64位的双精度浮点数。 类型位精度范围(绝对值)Float327位1.510-453.41038double641516位5.010-3241.710308如果一个二元操作符的运算数是浮点型,另一个运算数则必须是整数或浮点型的,运算时是这样进行处理的:如果一个运算数是一个整型数,那么这个运算数应转换为与另一个一样的浮点型形式:如果两者中有一个运算数为double型,那么另一个运算数应转换为double型。,2.2.3 浮点型,浮点数的运算包括赋值运算是不

22、会产生异常,相反当出现异常时,浮点数产生0,infinity或NaN,如下所述: 如果浮点运算无效,结果变为NaN。 如果一个浮点数或两个都是NaN,运算结果是NaN 如果浮点运算的结果太小,结果将变为正零或负零。 如果浮点运算的结果太大,结果将变为正无穷或负无穷。,2.2.4 结构类型,C#中的结构类型是包含构造函数、常量、字段、方法、属性、索引器、运算符和嵌套类型的值类型。其声明格式如下: 附加属性 修饰符 struct 结构类型名 :接口表 各成员声明 说明: 附加属性:附加的声明信息。 修饰符:允许的修饰符有new 和public、protected、internal、private的

23、有效组合,默认的访问性为private。 接口表:包含结构所实现的接口的列表。,2.2.5 枚举型,C#语言中引用了枚举型,“枚举”将变量可取得值全部列举出来。 枚举类型声明一组相关的符号常量定义了一个类型名。枚举具有代表性应用在“多选”中,其中运行期由编译期间的已知选项决定。其声明格式如下:附加属性 枚举修饰符 enum 枚举类型名 枚举基类型名 枚举值表 ,2.2.5 枚举型,例如: enum Myenum aa0, aa1, aa2 , aa3, aa4 , aa5 , aa6 ; /aa0为0,aa1为1 依次类推。 可以用显示数值分配重写枚举成员对应的枚举数值。 enum Myenu

24、m aa0=1, aa1, aa2 , aa3, aa4 , aa5 , aa6 ; /aa0为1,aa1为2 依次类推。,返回,2.3 引用类型,引用类型的变量存储的是对其数据对象(该实例)的引用。有可能两个变量引用相同的对象,对其中一个变量所引用对象的操作会影响到另一个变量所引用的对象。而对于值类型,每个变量都有它们自己的数据值,所以对一个变量的操作不可能影响到其他变量。,2.3.1 数组,数组是一组可以通过下标来访问的数。包含在数组中,变量又叫数组的元素,同一数组的数组元素具有相同的类型,此类型称为数组元素的类型。 数组的每个维度都有一个关联的长度(一个大于或等于零的整数)。数组类型声明

25、时只确定维数,维的长度不是数组类型的一部分,而是创建数组时被确定的。 数组中元素的类型可以是任何类型,包括数组类型。下面用一个数组初始化器初始化的数组: string MyArray=“ A”, “B”, “C”; 该简写效果等同于以下代码: MyArray=“ A”; MyArray= “B”;MyArray= “C”;,2.3.2 类,类定义了一种数据结构,它包括常量、字段、方法、属性、事件、索引、运算符、构造函数、析构函数和嵌套类型的说明。除了某些导入的外部方法,类及其成员在C#中的声明和实现通常需要放在一起。 类类型支持继承,因为这种机制派生的可以对基类进行扩展和特殊化。C#中仅允许单

26、个继承,类只能从一个基类继承实现。但一个类可以实现一个以上的接口,使用对象创建表达式来创建类实例。,2.3.2 类,每个成员都有一个访问可见性的标识,它们共有5种: public:访问不被限制。 protected:访问限制在包含类或包含类的派生类中。 internal:访问限制在本程序中内。 protected internal :访问限制在本程序中或包含类的派生类中。 private:访问限制在包含类中。,2.3.3 委托,在C语言或C+语言中,可以用“指向函数的指针”来实现函数参数的传递。而在C#中则专门定义了委托类型来实现这一功能。不过与C语言或C+函数指针不同,委托是完全针对对象的;

27、另外C+指针仅指向成员函数,而委托同时封装了对象实例和方法。 委托声明定义一个从System.Delegate类派生的类。在类型声明时,需要定义它引用的方法的参数类型和返回类型。创建委托实例时,将对实际方法的引用封装在该委托实例内。用一组适当的参数可以调用该委托实例,也就间接调用了所封装的方法,实现“匿名调用”,调用该委托时不必知道具体调用的是哪个方法。,2.3.3 委托,委托类型使用前必须用委托类型声明来定义,委托类型声明格式: 附加属性 委托修饰符 delegate 返回类型名 委托类型名(形参表); 说明: 附加属性:附加声明信息。 委托修饰符:允许的修饰符有new和四个访问修饰符。 返

28、回类型名:委托类型的返回类型,即所封装方法的返回类型。 委托类型名:委托类型名标识符。 形参表:指定委托的参数列表,相当于所封装方法的返回形参表,2.3.3 委托,C#中的委托类型是名称等效的,而不是结构等效的。具体地说,对于两个委托类型,即使它们具有相同的参数列表和返回类型,仍被认为是不同的两个委托类型。不过,这样两个彼此不同的但结构又相同的委托类型,它们的实例在比较时可以认为是相等关系。例如: delegate int Dlgt1(int i,double d); Class MyCLassA public static int M1(int a, double b) ,2.3.3 委托,

29、class MyClassB delegate int Dlgt2(int c,double d);public static int M1(int f, double g)public static void M2(int k,double l)public static int M3(int g)public static void M4(int g) 委托类型Dlg1和Dlg2都与方法MyClassA.M1和MyClassB.M1兼容,这是因为它们具有相同的返回类型和参数列表;但是委托类型是两个不同类型,所以它们是不可互换的。委托类型Dlgt1和Dlgt2与方法MyClassB.M2、M

30、yClassB.M3和MyClassB.M4不兼容,这是因为它们具有不同的返回类型或参数列表。,返回,2.4 异常处理,随着软件规模和复杂性不断增加,在程序中出现错误和不稳定代码的可能性也在随之增加。在现在的程序设计和实现中,大量的时间和精力都被花费在程序的测试、查找和修改错误上。程序的错误一般可以分为两种:编译错误和运行时错误。 1)编译错误:程序使用了错误的语法、函数、结构或是类等,这样的程序一般是无法被编译器正确编译通过的。 2)运行时错误:分为不可预料的逻辑错误和可预料的运行异常。,2.4 异常处理,不可预料的逻辑错误:是由于不当的设计造成的,对这类错误,只有通过长时间的、全面的测试才

31、能发现,一旦发现可以专门写一段错误处理程序,或是改进原来的逻辑设计。 可预料的运行异常:运行异常是可预料的,它是由系统的运行环境造成的。 那么什么是异常?其实,异常是一种程序定义的错误,它是对可能存在的运行时错误进行处理的一套机制,它对程序的逻辑错误进行设防,对运行异常加以控制。,2.4 异常处理,C# 可以处理在程序执行期间可能出现的异常情况。这些异常由正常程序流之外的代码处理。C# 提供了一种构造化的、统一的和类型安全的异常处理机制,既能处理系统级又能处理应用程序的异常。C#中的异常机制与C+中的很相似,但仍有以下几点不同: 1)在C#中,所有的异常都表示为一个类的对象,这个类必须为Sys

32、tem.Exception类或是它的派生类,而在C+中,任何类型的值都可以表示异常。 2)在C#中,异常处理有一个终结(finally)块,用来添加异常处理的结束代码,无论是正常执行还是异常条件,终结块都会被执行,而在C+中,只有通过复制处理代码的方法才能实现相同的功能。 3)在C#中,对于系统级的异常(如 溢出、除0和null引用等),系统都已提供了预定义好的异常类,所以它们可以等同于应用程序级的错误处理条件。,2.4 异常处理,在C#中异常处理的实现主要有下面4个步骤: 1)捕捉异常(try语句)将那些有可能产生异常的语句包含到try语句块中。 2)处理异常(catch语句)将针对异常的处

33、理语句放在catch语句块中,在特定的异常被捕获时执行处理语句。 3)清除异常(finally语句)无论try语句块中包含的语句是否产生异常,都要执行finally语句块中的语句。 4)抛出异常(throw异常)允许程序在某些条件下自己产生异常。,2.4.1 try块和catch块,try块和catch块组合完成捕获和处理异常的工作。在当前词法封装的try语句层中,一个try块后面可跟一或多个catch子句(为不同异常指定处理程序),构成try-catch语句,可以采用下列形式之一:,2.4.1 try块和catch块,采用从System.Exception派生的对象参数,处理特定的异常。 t

34、ry 代码块0 catch(异常对象) 代码块1 catch(异常对象) 代码块2 带任何参数的catch子句,它捕获任何类型的异常,称之为一般catch子句。 try 代码块0 catch 代码块1,2.4.1 try块和catch块,例题2.4 using System; class testApp static int zero=0;public static void Main()/捕捉异常try int a=100/zero; Console.WriteLine(“a=0“,a);,2.4.1 try块和catch块,/处理异常 /定义异常处理变量 catch(Exception e

35、) Console.WriteLine(“there is an Exception :“+e.Message); Console.WriteLine(“Afer exception handling !“); 输出结果: there is an Exception :试图除以零 Afer exception handling !,2.4.2 使用throw产生异常,执行时立即无条件地抛出一个指定的异常对象。其形式为:throw 异常对象 说明: 异常对象:throw语句的异常对象。抛出的异常必须是从System.Exception派生类型的对象,如: class MyException :

36、System.Exception throw new MyException( );,2.4.2 使用throw产生异常,例题2.5 using System; public class ThrowTest public static void Main()string s=null;,2.4.2 使用throw产生异常,if(s=null)throw (new ArgumentNullException();Console.WriteLine(“This string s is null“); /此句不被执行 输出结果: 未处理的异常:System.ArgumentNullException

37、:值不能为空 at ThrowTest.Main(),2.4.3 使用finally,清除异常(finally语句)无论try语句块中包含的语句是否产生异常,都要执行finally语句块中的语句。不管try是否成功执行,finally块一定会执行,这样保证了finally块是放置资源释放代码的理想位置,这些资源是在相应try块中,请求和操作的。如果try块成功执行,那么在try块终止后立即执行finally块,如果try块中出现异常,则在catch程序执行后,立即执行finally块。如果异常没有被try相关的某个catch块捕获或者和try块相关的catch处理,程序抛出一个异常,则执行fi

38、nally块,接着异常被下一个封装的try块处理。,2.4.3 使用finally,有try-finally和try-catch-finally两种组合: 1. try-finally组合 finally块用于释放在try块中分配的任何资源。即从try结构出去之前,控制总是传递给finally块,与try块的流程控制方式无关。Finally子句的一般形式:finally 代码块,2.4.3 使用finally,2. try-catch-finally组合 try-catch-finally一起使用时,通常是在try中获取并使用资源,在catch块中处理try语句块中出现的异常情况,在final

39、ly块中进行善后处理并释放资源。无论是否捕捉到异常,出本try层之前总要执行finally块。即try结构的流程控制必定是从try块进入,从finally块出去。与前面的try结构的流程控制方式无关。,返回,2.5 C#面向对象的编程,C#语言是完全面向对象的一种语言。C#秉承了C+面向对象的特性,支持面向对象的所有关键概念。在面向对象的语言中,类是非常重要的概念。C#没有C+中的全局常数和全局函数,一切都必须封装在一个类中。类是一个数据类型,它包含数据成员(常数和字段)、函数成员(方法、属性、事件、索引、操作符、构造函数和析构函数)和嵌套类型的描述,类类型的实例就是对象。,2.5.1 类的定

40、义,类的成员可以分为两大类:类本身所声明的,以及从基类中继承而来的。 类声明声明了一个新类。格式如下:附加属性 类修饰符 class 类名标示符 类基 类主体;,2.5.1 类的定义,类成员声明的规则: 构造函数和析构函数必须与直接包含它们的类有相同的名称。所有其它的成员则不能与直接包含它们的类同名。 常数、字段、事件或类型不能与在相同类中声明的其它成员同名。 方法的名称必须与同一个类中声明的其它非方法的名称不同。另外,同一个类中声明的各方法的签名(名称和形参表合起来)之间必须不同。 同一个类中声明的各索引的签名之间必须不同。 同一个类型声明的各操作符的签名之间必须不同。,2.5.2 继承,C

41、#是完全面向对象的程序设计语言,它拥有面向对象的程序的设计中最基本的特征,有良好的继承机制,它可以让派生类从它的基类继承成员。这样,已设计好的成熟的基类成员就可以通过继承充分地共享;在设计一个新的特殊类时,这些从基类继承的成员都可以直接引用不需重新设计。继承机制提高了代码的可重用性,减少了重复劳动,降低了开发难度,增强了软件的安全性和可靠性,加快了和软件开发的速度。,2.5.2 继承,C+允许多继承,派生类可以从多个直接基类继承,这往往会影响程序的可读性,并带来许多不安全的因素。C#则采用了更安全更容易理解的单继承和多接口实现的方式;但继承意味着派生类只能从一个直接基类继承,它直观安全;通过多

42、个接口实现的方式还可以间接地实现多继承的功能。 C#中,派生类包含了直接基类中除构造函数和析构函数外的所有的数据成员和函数成员成员。C#提供了大量的一般基类(标准类),用户开发新系统时可以从这些基类派生出新类,在继承基类原有成员的同时,还可以对基类进行扩展,以保证程序的灵活性。,2.5.2 继承,C#的继承要点如下: 1、继成具有共享特征,派生类可以共享基类的数据和代码。 2、继承有层次关系,有传递性。 3、继承有可扩展性,派生类可以增加新的成员,还可以对继承的成员进行特殊化,这部分是非共享的数据和代码,它使派生类和基类间具有差别,保证了程序的灵活性。但派生类不能被访问。,2.5.2 继承,4

43、、构造函数和析构函数不能被继承,其它所有成员都可以继承。 5、派生类可以通过声明同名新成员来隐藏继承的成员,然而被隐藏的继承成员并没有删除,它只是不能从派生类访问。 6、基类可以声明虚拟和抽象的函数成员,在派生类可以用重写成员来重写这些函数成员,实现运行时的多态性。,2.5.3 类的访问修饰符,在类声明中的类修饰符包括:new,public,protected,internal,private,abstract(抽象),sealed(密封)。 只有对嵌套类的声明才可使用new修饰符,表示隐藏了与所声明类同名的继承成员。修饰符abstract声明该类是抽象类,抽象类是不完整的,它只能作为其它类的

44、基类。抽象类不能被实例化,在抽象类上使用new操作符是错误的。sealed修饰符用来表示该类是密封类,密封类不能作其它类的基类,既不能派生其它类,sealed修饰符主要用于防止无意的派生。,2.5.3 类的访问修饰符,修饰符中有4个修饰符,它们是一些关键字,用于声明成员或类型的可访问性。 public(公共访问)是允许的最高访问级别,对于public成员或类型,访问不受限制。 protected(受保护的)访问仅限于包含类或从该类派生的类型。包含类即用它修饰的成员或类型所在类(含嵌套类),只有在所在类中以及从该类派生的类中访问它。,2.5.3 类的访问修饰符,internal访问仅限于当前项目

45、内,只有在同一程序集中的文件内才是可访问的。内部访问通常用于基于组件的开发,它使一组组件能够以内部方式进行合作,而不必向应用程序代码的其余部分公开。 private(私有的)私有访问是允许的最低访问级别。只能在所在的类(含嵌套类)和结构体中才是可访问的。,2.5.3 类的访问修饰符,4个访问修饰符可组成5种可访问性 public公共的 protected保护的 internal内部的 protected internal内部保护的 private私有的,2.5.4 构造函数和析构函数,1.构造函数 构造函数是执行对类或实例进行初始化的函数成员,在类被加载或实例被创建时,构造函数自动被调用。 在

46、编写程序的时候,构造函数不同于其他成员函数,它们的名字与它们所属的类相同。当某类对象创建或拷贝时,要隐含调用相应的构造函数。,2.5.4 构造函数和析构函数,实例构造函数 实例构造函数是创建实例时,用于执行对类的实例进行初始化的函数成员,实例构造函数是使用构造函数声明来声明来声明的,格式为:附加属性 构造函数修饰符 标识符(形参表) 构造函数体,2.5.4 构造函数和析构函数,例如: class A int x = 0 , y=0 , count; public A( ) count = 0 ; /声明不带参数public A( int vx , int vy ) x = vx ; y = v

47、y ; /声明带参数的实例构造函数 ,2.5.4 构造函数和析构函数,静态构造函数: 静态构造函数是实现对一个类进行初始化的函数成员。静态构造函数不能有参数,不能有修饰符而且不能被调用,当类被加载时,类的静态构造函数自动被调用。 静态构造函数是使用静态构造函数声明来声明的,声明格式为:附加属性 extern static 标识符 () 构造函数体,2.5.4 构造函数和析构函数,静态构造函数执行的时间是依赖于实现的,必须遵循以下规则: 只有执行一个类的静态构造函数之后,才能创建该类的任何实例。 只有执行某个类的静态构造函数之后,才能引用该类的任何静态成员 在单个程序实例化过程中,类的静态构造函

48、数最多执行一次。,2.5.4 构造函数和析构函数,2.析构函数 析构函数是在撤销类的实例时调用的函数成员,所以又称为实例析构函数。析构函数名与类名相同,只有前面加一个符号。析构函数是使用析构函数声明来声明的:附加属性 extern 标示符 () 析构函数体,2.5.4 构造函数和析构函数,析构函数不带参数,而且不能被显式调用。析构函数在系统进行碎片收集时会被自动调用。当任何代码都不能再使用某个实例时,该实例就符合撤销的条件。符合撤销条件之后的某个时刻会执行实例的析构函数。当撤销实例时,按照从派生程度最大到派生程度最小的顺序调用它的继承链中的析构函数。 由于析构函数要求不带参数,因此它不能被重载

49、。所以,一个类只能有一个析构函数。,2.5.5 this和static关键字,1.this关键字 关键字this表示对当前实例的引用,不表示静态的引用。保留字this访问仅限于在构造函数、实例方法和类的实例中使用,不能在静态方法、静态属性访问器或字段声明的初始化式中使用。this访问的含义是:,2.5.5 this和static关键字,在类的构造函数中出现的this表示对正在创建的对象的引用。 在实例方法中,它表示对调用该方法的对象的引用。 在结构的构造函数中出现的this表示对正在构造的结构的引用。 在结构的方法中出现的this表示对调用该方法的结构的引用。,2.5.5 this和static关键字,2.static关键字 常量或类型声明隐含声明为静态成员。其他各种成员用static关键字声明为静态成员。静态成员有以下几种特征: 1)以E.M形式访问静态成员时,E必须为一个类,不能是实例。 2)类中的静态字段仅分配一个存储单元。无论类中有多少实例被创建,也仅有一个静态字段的拷贝。 3)类的静态函数成员中不能用简单名称访问实例成员,在静态函数成员中使用this是错误的。,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报