C程序设计教程第4章

上传人:无*** 文档编号:169458629 上传时间:2022-11-15 格式:PPT 页数:62 大小:373.52KB
收藏 版权申诉 举报 下载
C程序设计教程第4章_第1页
第1页 / 共62页
C程序设计教程第4章_第2页
第2页 / 共62页
C程序设计教程第4章_第3页
第3页 / 共62页
资源描述:

《C程序设计教程第4章》由会员分享,可在线阅读,更多相关《C程序设计教程第4章(62页珍藏版)》请在装配图网上搜索。

1、2022-11-151第四章第四章 面向对象程序设计入门面向对象程序设计入门1.总体要求总体要求l理解面向对象的基本概念,正确区分类和对象,对象的声明理解面向对象的基本概念,正确区分类和对象,对象的声明和对象的创建。和对象的创建。l掌握类的定义与使用方法,正确定义类的数据成员、属性和掌握类的定义与使用方法,正确定义类的数据成员、属性和方法。方法。l理解类的可访问性、正确使用访问修饰符控制对类成员的访理解类的可访问性、正确使用访问修饰符控制对类成员的访问。问。l掌握类的方法的定义、调用与重载,理解方法的参数传递的掌握类的方法的定义、调用与重载,理解方法的参数传递的工作机制。工作机制。l理解值类型

2、和引用类型的区别。理解值类型和引用类型的区别。l理解构造函数与析构函数的作用,掌握其使用方法。理解构造函数与析构函数的作用,掌握其使用方法。l方法的重载和参数传递方法的重载和参数传递2.相关知识点相关知识点l熟悉熟悉C#中数据类型、表达式、运算符、常量与变量等基础中数据类型、表达式、运算符、常量与变量等基础知识。知识。l熟悉熟悉C#中数据类型转换。中数据类型转换。3.学习重点学习重点lC#中类的定义、类的数据成员、属性和方法中类的定义、类的数据成员、属性和方法l类的构造函数类的构造函数l方法的重载和参数传递方法的重载和参数传递第四章第四章 面向对象程序设计入门面向对象程序设计入门 4.学习难点

3、学习难点l类和对象的关系类和对象的关系l方法的重载和参数传递方法的重载和参数传递l值类型和引用类型及对象的生命周期值类型和引用类型及对象的生命周期第四章第四章 面向对象程序设计入门面向对象程序设计入门 第四章第四章 面向对象程序设计入门面向对象程序设计入门面向对象的基本概念面向对象的基本概念 类的定义类的定义类的方法类的方法构造函数构造函数2022-11-156l4.1.1 对象对象l4.1.2 事件与方法事件与方法l4.1.3 类与对象类与对象l4.1.4 抽象、封装、继承与多态抽象、封装、继承与多态 2022-11-157对象对象l客观世界中任何一个事物都可以看成一个对象客观世界中任何一个

4、事物都可以看成一个对象(object),对象可以是自然物体(如汽车、房屋、狗),也可以是社对象可以是自然物体(如汽车、房屋、狗),也可以是社会生活中一种逻辑结构(如班级、部门、组织),甚至一会生活中一种逻辑结构(如班级、部门、组织),甚至一篇文章、一个图形、一项计划等都可以视作对象。对象是篇文章、一个图形、一项计划等都可以视作对象。对象是构成系统的基本单位,在实际社会生活中,人们都是在不构成系统的基本单位,在实际社会生活中,人们都是在不同的对象中活动的。同的对象中活动的。l任何一个对象都应当具有这两个要素,即属性任何一个对象都应当具有这两个要素,即属性(attribute)和行为和行为(beh

5、avior),一个对象往往由一组属性和一组行为,一个对象往往由一组属性和一组行为构成,一辆汽车是一个对象,它的属性是生产厂家、品牌、构成,一辆汽车是一个对象,它的属性是生产厂家、品牌、型号、颜色、价格等,它是行为是它的功能,如发动、停型号、颜色、价格等,它是行为是它的功能,如发动、停止、加速等,一般来说,凡是具备属性和行为这两个要素止、加速等,一般来说,凡是具备属性和行为这两个要素的,都可以作为对象,的,都可以作为对象,对象对象l对象是问题域中某些事物的一个抽象,反映事物对象是问题域中某些事物的一个抽象,反映事物在系统中需要保存的必要信息和发挥的作用,是在系统中需要保存的必要信息和发挥的作用,

6、是包含一些特殊属性(数据)和服务(行为方法)包含一些特殊属性(数据)和服务(行为方法)的封装实体。具体来说,他应有唯一的名称,有的封装实体。具体来说,他应有唯一的名称,有一系列状态(表示为数据),有表示对象行为的一系列状态(表示为数据),有表示对象行为的一系列行为(方法),简言之:一系列行为(方法),简言之:l对象对象=属性属性+行为(方法、操作)行为(方法、操作)4.1.2 事件与方法事件与方法l事件(事件(Event)又称为消息()又称为消息(Message),表示),表示向对象发出的服务请求。方法(向对象发出的服务请求。方法(Method)表示对)表示对象能完成的服务或执行的操作功能。象

7、能完成的服务或执行的操作功能。l在一个系统中的多个对象之间通过一定的渠道相在一个系统中的多个对象之间通过一定的渠道相互联系,要使某一个对象实现某一种行为或操作互联系,要使某一个对象实现某一种行为或操作,应当向他传送相应的消息。例如想让汽车行驶,应当向他传送相应的消息。例如想让汽车行驶,必须由人去踩油门,向汽车发出相应的信号。,必须由人去踩油门,向汽车发出相应的信号。对象之间就是这样通过发送和接收消息互相联系对象之间就是这样通过发送和接收消息互相联系的。的。l在面向对象的概念中,一个对象可以有多个方法,提供多在面向对象的概念中,一个对象可以有多个方法,提供多种服务,完成多种操作功能。但这些方法只

8、有在另外一个种服务,完成多种操作功能。但这些方法只有在另外一个对象向他发出请求之后(发生事件)才会被执行。对象向他发出请求之后(发生事件)才会被执行。4.1.3 类与对象类与对象l普通逻辑意义上的类是现实世界中各种实体的抽普通逻辑意义上的类是现实世界中各种实体的抽象概念,而对象是现实生活中的一个个实体,例象概念,而对象是现实生活中的一个个实体,例如,在现实世界中大量具体一辆辆汽车、摩托车如,在现实世界中大量具体一辆辆汽车、摩托车、自行车等实体是对象,而交通工具则是这些对、自行车等实体是对象,而交通工具则是这些对象的抽象,交通工具就是一个类。象的抽象,交通工具就是一个类。l在面向对象的概念中,类

9、(在面向对象的概念中,类(Class)表示具有相同)表示具有相同属性和行为的一组对象的集合,为该类的所有对属性和行为的一组对象的集合,为该类的所有对象提供统一的抽象描述。象提供统一的抽象描述。l类是对相似对象的抽象,而对象是该类的一个特类是对相似对象的抽象,而对象是该类的一个特例,类与对象的关系是抽象与具体的关系。例,类与对象的关系是抽象与具体的关系。4.1.4 抽象、封装、继承与多态抽象、封装、继承与多态l面向对象的最基本的特征是抽象性、封装性、继承性和多面向对象的最基本的特征是抽象性、封装性、继承性和多态性。态性。l1抽象抽象l抽象(抽象(abstraction)是处理事物复杂性的方法,只

10、关注与)是处理事物复杂性的方法,只关注与当前目标有关的方面,而忽略与当前目标无关的那些方面当前目标有关的方面,而忽略与当前目标无关的那些方面,例如在学生成绩管理中,张三、李四、王五作为学生,例如在学生成绩管理中,张三、李四、王五作为学生,我们只关心他们和成绩管理有关的属性和行为,如学号、我们只关心他们和成绩管理有关的属性和行为,如学号、姓名、成绩、专业等特性。抽象的过程是将有关事物的共姓名、成绩、专业等特性。抽象的过程是将有关事物的共性归纳、集中的过程,例如凡是有轮子、能滚动并前进的性归纳、集中的过程,例如凡是有轮子、能滚动并前进的陆地交通工具统称为陆地交通工具统称为“车子车子”,把其中用汽油

11、发动机驱动,把其中用汽油发动机驱动的抽象为的抽象为“汽车汽车”,把用马拉的抽象为,把用马拉的抽象为“马车马车”。4.1.4 抽象、封装、继承与多态抽象、封装、继承与多态l抽象能表示同一类事物的本质,如果你会使用自己家里的抽象能表示同一类事物的本质,如果你会使用自己家里的电视机,在别人家里看到即便是不同的牌子的电视机,你电视机,在别人家里看到即便是不同的牌子的电视机,你也能对它进行操作。因这它具有所有电视机所共有的特征也能对它进行操作。因这它具有所有电视机所共有的特征,而,而C#中的数据类型就是对一系列具体的数的抽象,例如中的数据类型就是对一系列具体的数的抽象,例如:int是对所有整数的抽象,是

12、对所有整数的抽象,double是对所有双精度浮点型是对所有双精度浮点型数的抽象。数的抽象。l2封装和信息隐藏封装和信息隐藏l封装(封装(encapsulation)有两个方面的含义:一是将)有两个方面的含义:一是将有关的数据和操作代码封装在一个对象中,形成一个有关的数据和操作代码封装在一个对象中,形成一个基本单位,各个对象之间相对独立,互不干扰。二是基本单位,各个对象之间相对独立,互不干扰。二是将对象中某些部份对外隐藏,即隐藏其内部细节,只将对象中某些部份对外隐藏,即隐藏其内部细节,只留下少量接口,以便与外界联系,接收外界的消息。留下少量接口,以便与外界联系,接收外界的消息。这种对外界隐藏的做

13、法称为信息隐藏(这种对外界隐藏的做法称为信息隐藏(information hiding)。信息隐藏还有利于数据安全,防止无关的)。信息隐藏还有利于数据安全,防止无关的人了解和修改数据。人了解和修改数据。4.1.4 抽象、封装、继承与多态抽象、封装、继承与多态l封装把对象的全部属性和全部行为结合在一起形成一个不封装把对象的全部属性和全部行为结合在一起形成一个不可分割的独立单位。而通过信息隐蔽技术,用户只能见到可分割的独立单位。而通过信息隐蔽技术,用户只能见到对象封装界面上的信息,对象内部对用户是隐蔽的。对象封装界面上的信息,对象内部对用户是隐蔽的。l例如,一台电视机就是一个封装体。从设计者的角度

14、来讲例如,一台电视机就是一个封装体。从设计者的角度来讲,不仅需要考虑内部的各种元器件,还要考虑主机板、显,不仅需要考虑内部的各种元器件,还要考虑主机板、显像管等元器件的连接与组装;从使用者的角度来讲,只关像管等元器件的连接与组装;从使用者的角度来讲,只关心其型号、颜色、重量等属性,只关心电源开关按钮、音心其型号、颜色、重量等属性,只关心电源开关按钮、音量开关、调频按钮、视频输入输出接口等用起来是否方便量开关、调频按钮、视频输入输出接口等用起来是否方便,根本不用关心其内部构造。,根本不用关心其内部构造。l因此,封装的目的在于将对象的使用者与设计者分开,使因此,封装的目的在于将对象的使用者与设计者

15、分开,使用者不必了解对象行为的具体实现,只需要用设计者提供用者不必了解对象行为的具体实现,只需要用设计者提供的消息接口来访问该对象。的消息接口来访问该对象。4.1.4 抽象、封装、继承与多态抽象、封装、继承与多态4.1.4 抽象、封装、继承与多态抽象、封装、继承与多态l3继承继承l汽车制造厂要生产新型号的汽车,如果全部从头开始设计汽车制造厂要生产新型号的汽车,如果全部从头开始设计,将耗费大力的人力、物力和财力。但如果选择已有的某,将耗费大力的人力、物力和财力。但如果选择已有的某一型号的汽车为基础,再增加一些新的功能,就能快速研一型号的汽车为基础,再增加一些新的功能,就能快速研发出新型号的汽车。

16、这是提高生产效率的常用方法。发出新型号的汽车。这是提高生产效率的常用方法。l如果在软件开发中已建立了一个名为如果在软件开发中已建立了一个名为A的类,又想建立一的类,又想建立一个名为个名为B的类,而后者与前者内容基本相同,只是在前者的类,而后者与前者内容基本相同,只是在前者基础上增加一些新的属性和行为,显然不必再从头设计一基础上增加一些新的属性和行为,显然不必再从头设计一个新类,只需在个新类,只需在A类的基础上增加一些新的内容即可,而类的基础上增加一些新的内容即可,而B类的对象拥有类的对象拥有A类的全部属性与方法,称作类的全部属性与方法,称作B类对类对A类的继类的继承,在承,在B类中不必重新定义

17、已在类中不必重新定义已在A类中定义过的属性和方法类中定义过的属性和方法,这种特性在面向对象中称作对象的继承性。继承在,这种特性在面向对象中称作对象的继承性。继承在C#中中称为派生,其中,称为派生,其中,A类称为基类或父类,类称为基类或父类,B类称为派生类或类称为派生类或子类。子类。4.1.4 抽象、封装、继承与多态抽象、封装、继承与多态l继承机制的优势在于降低了软件开发的复杂性和继承机制的优势在于降低了软件开发的复杂性和费用,使软件系统易于扩充,大大缩短了软件开费用,使软件系统易于扩充,大大缩短了软件开发周期,对于大型软件的开发具有重要的意义。发周期,对于大型软件的开发具有重要的意义。4.1.

18、4 抽象、封装、继承与多态抽象、封装、继承与多态l4多态多态l多态性(多态性(polymorphism)是指在基类中定义的属性或方)是指在基类中定义的属性或方法被派生类继承后,可以具有不同的数据类型或表现出不法被派生类继承后,可以具有不同的数据类型或表现出不同的行为。其对象对同一消息会做出不同的响应,如张三同的行为。其对象对同一消息会做出不同的响应,如张三、李四和王五是分别是属于三个班的三个学生,在听到上、李四和王五是分别是属于三个班的三个学生,在听到上课铃声后,他们会分别走进课铃声后,他们会分别走进3个不同的教室,同样,个不同的教室,同样,“启动启动”是所有交通工具都具有的操作,但不同的具体

19、交通工具是所有交通工具都具有的操作,但不同的具体交通工具其其“启动启动”操作的具体实现是不同的,如汽车的启动是操作的具体实现是不同的,如汽车的启动是“发动机点火,启动引擎发动机点火,启动引擎”,启动轮船时要,启动轮船时要“起锚起锚”,气球,气球飞艇启动是飞艇启动是“充气,解缆充气,解缆”,为了实现多态性,需要在派,为了实现多态性,需要在派生类中更改从基类中自动继承来的数据类型或方法。这种生类中更改从基类中自动继承来的数据类型或方法。这种为了替换基类的部分内容而在派生类中重新进行定义的操为了替换基类的部分内容而在派生类中重新进行定义的操作,在面向对象的概念中称为覆盖。这样一来,不同类的作,在面向

20、对象的概念中称为覆盖。这样一来,不同类的对象可以响应同名的消息(方法)来完成特定的功能,但对象可以响应同名的消息(方法)来完成特定的功能,但其具体的实现方法却可以不同。其具体的实现方法却可以不同。4.2 类的定义类的定义l4.2.1 类的声明和实例化类的声明和实例化 l4.2.2 类的数据成员和属性类的数据成员和属性l4.2.3 类的可访问性类的可访问性l4.2.4 值类型与引用类型值类型与引用类型4.2.1 类的声明和实例化类的声明和实例化 l1类的声明类的声明l类的声明一般形式如下:类的声明一般形式如下:访问修饰符访问修饰符 class 类名类名:基类基类 类的成员类的成员;l其中,访问修

21、饰符用来限制类的作用范围或访问级别,可其中,访问修饰符用来限制类的作用范围或访问级别,可省略;类名是一个合法的省略;类名是一个合法的C#标识符,推荐使用标识符,推荐使用Pascal命名命名规范,规范,Pascal命名规范要求名称的每个单词的首字母要大命名规范要求名称的每个单词的首字母要大写;基类表明所定义的类是一个派生类,可省略;类的成写;基类表明所定义的类是一个派生类,可省略;类的成员放在花括号中,构成类的主体,用来定义类的属性和行员放在花括号中,构成类的主体,用来定义类的属性和行为。类的成员包括常量、字段、属性、索引器、方法、事为。类的成员包括常量、字段、属性、索引器、方法、事件、构造函数

22、等。件、构造函数等。4.2.1 类的声明和实例化类的声明和实例化l2类的实例类的实例l定义类之后,可以用定义的类声明对象,然后再通过这个定义类之后,可以用定义的类声明对象,然后再通过这个对象来访问其数据或调用其方法。对象来访问其数据或调用其方法。l(1)对象的声明与创建。对象的声明与创建。l声明对象的格式与声明基本数据类型的格式相同,其语法声明对象的格式与声明基本数据类型的格式相同,其语法格式为:格式为:l类名类名 对象名对象名l例如:例如:lStudent stu1;/声明一个声明一个Student对象对象stu14.2.1 类的声明和实例化类的声明和实例化l但是,对象声明后需要用但是,对象

23、声明后需要用“new”关键字将对象实例化,关键字将对象实例化,这样才能为对象在内存中分配保存数据空间,实例化的语这样才能为对象在内存中分配保存数据空间,实例化的语法格式为:法格式为:对象名对象名=new 类名类名();例如:例如:stu1=new Student();/为为stu1分配内存空间分配内存空间l也可以在声明对象同时实例化对象。语法格式为:也可以在声明对象同时实例化对象。语法格式为:类名类名 对象名对象名=new 类名类名();例如:例如:Student stu2=new Student();/声明同时创建对象声明同时创建对象4.2.1 类的声明和实例化类的声明和实例化l(2)类成员

24、的访问。类成员的访问。l类成员有两种访问方式:一种是在类的内部访问,另一种类成员有两种访问方式:一种是在类的内部访问,另一种是在类的外部访问。是在类的外部访问。l在类的内部访问类的成员,表示一个类成员要使用当前类在类的内部访问类的成员,表示一个类成员要使用当前类中的其他成员,可以直接使用成员名称,有时为了避免引中的其他成员,可以直接使用成员名称,有时为了避免引起混淆,也可采用如下形式:起混淆,也可采用如下形式:lthis.类成员类成员l其中,其中,this表示当前对象,是表示当前对象,是C#的关键字。的关键字。4.2.1 类的声明和实例化类的声明和实例化l【实例【实例4-1】定义】定义Stud

25、ent类并实例化类的对象。类并实例化类的对象。4.2.2 类的数据成员和属性类的数据成员和属性l类的成员包括类的常量、字段、属性、索引器、方法、事类的成员包括类的常量、字段、属性、索引器、方法、事件、构造函数等,其中,常量、字段和属性都是与类的数件、构造函数等,其中,常量、字段和属性都是与类的数据有关的成员。据有关的成员。l1常量常量l常量的值是固定不变的。类的常量成员是一种符号常量,常量的值是固定不变的。类的常量成员是一种符号常量,符号常量是由用户根据需要自行创建的常量,在程序设计符号常量是由用户根据需要自行创建的常量,在程序设计过程中可能需要反复使用到某个数据,如圆周率过程中可能需要反复使

26、用到某个数据,如圆周率3.1415926,如果在代码中反复书写,不仅麻烦而且容易,如果在代码中反复书写,不仅麻烦而且容易出现书名错误,此时,可考虑将其声明为一个符号常量,出现书名错误,此时,可考虑将其声明为一个符号常量,用户定义符号常量使用用户定义符号常量使用const关键字,在定义时,必须指关键字,在定义时,必须指定名称和值,其一般形式如下:定名称和值,其一般形式如下:l访问修饰符访问修饰符 const 数据类型数据类型 常量名常量名=常量的值常量的值;4.2.2 类的数据成员和属性类的数据成员和属性l2字段字段l字段表示类的成员变量,字段的值代表某个对象的数据状字段表示类的成员变量,字段的

27、值代表某个对象的数据状态。不同的对象,数据状态不同,意味着各字段的值也不态。不同的对象,数据状态不同,意味着各字段的值也不同。声明字段的方法与定义普通变量的方法相同,其一般同。声明字段的方法与定义普通变量的方法相同,其一般格式如下:格式如下:l访问修饰符访问修饰符 数据类型数据类型 字段名字段名;l其中,访问修饰符用来控制字段的访问级别,可省略。例其中,访问修饰符用来控制字段的访问级别,可省略。例如:如:lpublic double radius;4.2.2 类的数据成员和属性类的数据成员和属性l3属性属性l字段和常量描述了类的数据,当这些数据允许外界访问时,可以使用字段和常量描述了类的数据,

28、当这些数据允许外界访问时,可以使用访问修饰符访问修饰符public,不允许外界访问时,可以使用,不允许外界访问时,可以使用private或或protected l定义属性的一般形式如下:定义属性的一般形式如下:l访问修饰符访问修饰符 数据类型数据类型 属性名属性名l get /获取属性的代码,用获取属性的代码,用return 返回值返回值 set /设置属性的代码,用设置属性的代码,用value赋值赋值 4.2.2 类的数据成员和属性类的数据成员和属性l【实例【实例4-2】定义类的数据成员及属性。】定义类的数据成员及属性。4.2.3 类的可访问性类的可访问性l为了控制类和类成员的作用范围或访问

29、级别,为了控制类和类成员的作用范围或访问级别,C#提供了访问修提供了访问修饰符,用于限制对类和类成员的访问属性。这些访问修饰符包饰符,用于限制对类和类成员的访问属性。这些访问修饰符包括括public、private、internal、protected、protected internall在使用访问修饰符来定义命名空间、结构和类及其成员时,要在使用访问修饰符来定义命名空间、结构和类及其成员时,要注意以下几点。注意以下几点。l(1)一个成员或类型只能有一个访问修饰符,使用一个成员或类型只能有一个访问修饰符,使用 protected internal 组合时除外。组合时除外。l(2)命名空间上不

30、允许使用访问修饰符,命名空间没有访问限制命名空间上不允许使用访问修饰符,命名空间没有访问限制。l(3)如果未指定访问修饰符,则使用默认的可访问性,类的成员如果未指定访问修饰符,则使用默认的可访问性,类的成员默认为默认为private,如实例,如实例4-2中的中的pi没有指定访问修饰符,默认为没有指定访问修饰符,默认为private。l(4)第一级类型(指不嵌套在其他类型中的类型)的可访问性只第一级类型(指不嵌套在其他类型中的类型)的可访问性只能是能是internal或或public,默认可访问性是,默认可访问性是internal,如实例,如实例4-2中中的的Circle类没有指定访问修饰符,默

31、认为类没有指定访问修饰符,默认为internal。4.2.4 值类型与引用类型值类型与引用类型lC#将数据类型分为值类型将数据类型分为值类型(value type)和引用类型和引用类型(reference type)。l1值类型值类型l值类型变量直接包含其本身的数据,前面提到的值类型变量直接包含其本身的数据,前面提到的简单类型简单类型(int、bool、char、float、double、decimal)、结构类型、结构类型(struct)、枚举类型、枚举类型(enum)等等都是值类型。在定义一个值类型变量后,将直接都是值类型。在定义一个值类型变量后,将直接为该变量分配空间,可以直接赋值和使用

32、。为该变量分配空间,可以直接赋值和使用。4.2.4 值类型与引用类型值类型与引用类型l引用类型引用类型l与值类型不同,引用类型变量本身并不包含数据,只是存与值类型不同,引用类型变量本身并不包含数据,只是存储对数据的引用,数据保存在其他位置,数组、字符串、储对数据的引用,数据保存在其他位置,数组、字符串、类和后面要介绍的接口、委托等都属于引用类型。引用型类和后面要介绍的接口、委托等都属于引用类型。引用型变量在定义时并不会分配空间,只是在对其实例化后才真变量在定义时并不会分配空间,只是在对其实例化后才真正的分配存储空间。正的分配存储空间。4.2.4 值类型与引用类型值类型与引用类型l3装箱和折箱装

33、箱和折箱l对于值类型来说,可以通过隐式转换方法或显示转换方法对于值类型来说,可以通过隐式转换方法或显示转换方法进行数据转换;对于引用类型来说,进行数据转换;对于引用类型来说,C#同样允许将任何类同样允许将任何类型的数据转换为对象,或者将任何类型的对象转换为与之型的数据转换为对象,或者将任何类型的对象转换为与之兼容的数据类型。兼容的数据类型。lC#把值类型转换为对象的操作称为装箱,而把对象转换为把值类型转换为对象的操作称为装箱,而把对象转换为兼容的值类型的操作称为拆箱。兼容的值类型的操作称为拆箱。C#的这种装箱与拆箱操作的这种装箱与拆箱操作类似于收发邮政包裹,发送包裹之前先装箱打包,收到包类似于

34、收发邮政包裹,发送包裹之前先装箱打包,收到包裹后再拆箱解包。裹后再拆箱解包。l装箱意味着把一个值类型的数据转换为一个对象类型的数装箱意味着把一个值类型的数据转换为一个对象类型的数据,装箱过程是隐式转换过程,由系统自动完成,据,装箱过程是隐式转换过程,由系统自动完成,C#中中Object类是所有类的最终基类,因此,可以将一个值类型类是所有类的最终基类,因此,可以将一个值类型变量直接赋值给变量直接赋值给Object对象对象 4.3 类的方法类的方法l4.3.1 方法的声明与调用方法的声明与调用 l4.3.2 方法的参数传递方法的参数传递l4.3.3 方法的重载方法的重载 4.3.1 方法的声明与调

35、用方法的声明与调用 l方法的使用分声明与调用两个环节。方法的使用分声明与调用两个环节。l1方法的声明方法的声明l声明方法的一般形式如下:声明方法的一般形式如下:访问修饰符访问修饰符 返回值类型返回值类型 方法名方法名(参数列表参数列表)语句语句;return 返回值返回值;4.3.1 方法的声明与调用方法的声明与调用 l(1)访问修饰符控制方法的访问级别,可用于方法的修访问修饰符控制方法的访问级别,可用于方法的修饰符包括饰符包括public、protected、private和和internal等;等;访问修饰符是可选的,默认情况下为访问修饰符是可选的,默认情况下为 privatel(2)方法

36、的返回类型用于指定由该方法计算和返回的值方法的返回类型用于指定由该方法计算和返回的值的类型,可以是任何合法的数据类型,包括值类型和的类型,可以是任何合法的数据类型,包括值类型和引用类型,如果一个方法不返回一个值,则返回值类引用类型,如果一个方法不返回一个值,则返回值类型使用型使用void关键字来表示;关键字来表示;l(3)方法名必须符合方法名必须符合C#的命名规范,与变量名的命名的命名规范,与变量名的命名规则相同;规则相同;4.3.1 方法的声明与调用方法的声明与调用l(4)参数列表是方法可以接受的输入数据,当方法不需要参参数列表是方法可以接受的输入数据,当方法不需要参数时,可省略参数列表,但

37、不能省略圆括号;当参数不止数时,可省略参数列表,但不能省略圆括号;当参数不止一个时,需要使用逗号分隔,同时每一个参数都必须声明一个时,需要使用逗号分隔,同时每一个参数都必须声明数据类型,即使这些参数的数据类型相同也不例外;数据类型,即使这些参数的数据类型相同也不例外;l(5)花括号中的内容为方法的主体,由若干条语句组成,每花括号中的内容为方法的主体,由若干条语句组成,每一条语句都必须使用分号结尾。当方法结束时如果需要返一条语句都必须使用分号结尾。当方法结束时如果需要返回操作结果,则使用回操作结果,则使用return语句返回,并且返回的值的类语句返回,并且返回的值的类型要与返回值的类型相匹配。如

38、果使用型要与返回值的类型相匹配。如果使用void标记方法为无标记方法为无返回值的方法,可省略返回值的方法,可省略return语句。语句。4.3.1 方法的声明与调用方法的声明与调用l2方法的调用方法的调用l一个方法一旦在某个类中声明,就可由其他方法调用,调一个方法一旦在某个类中声明,就可由其他方法调用,调用者既可以是同一个类中的方法,也可以是其他类中的方用者既可以是同一个类中的方法,也可以是其他类中的方法。如果调用者是同一个类的方法,则可以直接调用,如法。如果调用者是同一个类的方法,则可以直接调用,如果调用者是其他类中的方法,则需要通过类的实例来引用果调用者是其他类中的方法,则需要通过类的实例

39、来引用,但静态方法例外,静态方法通过类名直接调用,但静态方法例外,静态方法通过类名直接调用 l(1)在方法声明的类定义中调用该方法。其语法格式为:在方法声明的类定义中调用该方法。其语法格式为:方法名方法名(参数列表参数列表)l(2)在方法声明的类定义外部调用该方法,需要通过类声明在方法声明的类定义外部调用该方法,需要通过类声明的对象调用该方法,其格式为:的对象调用该方法,其格式为:对象名对象名.方法名方法名(参数列表参数列表)4.3.2 方法的参数传递方法的参数传递l在声明方法时,所定义的参数是形式参数(简称形参),在声明方法时,所定义的参数是形式参数(简称形参),这些参数的值由调用方负责为其

40、传递,调用方传递的是实这些参数的值由调用方负责为其传递,调用方传递的是实际数据,称为实际参数(简称实参),调用方必须严格按际数据,称为实际参数(简称实参),调用方必须严格按照被调用的方法所定义的参数类型和顺序指定实参。在调照被调用的方法所定义的参数类型和顺序指定实参。在调用方法时,参数传递就是将实参传递给形参的过程。用方法时,参数传递就是将实参传递给形参的过程。l方法的参数传递按性质可分为按值传递与按引用传递。方法的参数传递按性质可分为按值传递与按引用传递。4.3.2 方法的参数传递方法的参数传递l1按值传参按值传参l按值传参时,把实参变量的值赋给相对应的形参变量,即按值传参时,把实参变量的值

41、赋给相对应的形参变量,即被调用的方法所接收到的只是实参数据值的一个副本。当被调用的方法所接收到的只是实参数据值的一个副本。当在方法内部更改了形参变量的数据值时,不会影响实参变在方法内部更改了形参变量的数据值时,不会影响实参变量的值,即实参变量和形参变量是两个不相同的变量,他量的值,即实参变量和形参变量是两个不相同的变量,他们具有各自的内存地址和数据值。因此,实参变量的值传们具有各自的内存地址和数据值。因此,实参变量的值传递给形参变量时是一种单向值传递。递给形参变量时是一种单向值传递。l值类型的参数在传递时默认为按值传参。值类型的参数在传递时默认为按值传参。string和和object虽然是引用

42、型数据,但从表现形式来看,其具有按值传参虽然是引用型数据,但从表现形式来看,其具有按值传参的效果。的效果。4.3.2 方法的参数传递方法的参数传递l【实例【实例4-3】用值传参进行参数值交换】用值传参进行参数值交换 4.3.2 方法的参数传递方法的参数传递l2按引用传参按引用传参l方法只能返回一个值,但在实际应用中常常需要方法能够返回方法只能返回一个值,但在实际应用中常常需要方法能够返回多个值或修改传入的参数值并返回,如果需要完成以上任务,多个值或修改传入的参数值并返回,如果需要完成以上任务,只用只用return语句是无法做到的,这时可以使用按引用传递参数的语句是无法做到的,这时可以使用按引用

43、传递参数的方式来实现。方式来实现。l调用方向方法传递引用型参数时,调用方将把实参变量的引用调用方向方法传递引用型参数时,调用方将把实参变量的引用赋给相对应的形参变量。实参变量的引用代表数据值的内存地赋给相对应的形参变量。实参变量的引用代表数据值的内存地址,因此,形参变量和实参变量将指向同一个引用。如果在方址,因此,形参变量和实参变量将指向同一个引用。如果在方法内部更改了形参变量所引用的数据值,则同时也修改了实参法内部更改了形参变量所引用的数据值,则同时也修改了实参变量所引用的数据值。变量所引用的数据值。l当值类型和当值类型和string类型参数要按引用方式传参时,可以通过类型参数要按引用方式传

44、参时,可以通过ref关键字来声明引用参数,无论是形参还是实参,只要希望传递关键字来声明引用参数,无论是形参还是实参,只要希望传递数据的引用,就必须添加数据的引用,就必须添加ref关键字。关键字。4.3.2 方法的参数传递方法的参数传递l【实例【实例4-4】用引用传参进行参数值交换。】用引用传参进行参数值交换。(1)将【实例将【实例4-3】Swap方法声明改为引用型参数:方法声明改为引用型参数:public string Swap(ref int x,ref int y)(2)将【实例将【实例4-3】Swap方法调用改为引用型传参:方法调用改为引用型传参:lblShow.Text=s.Swap(

45、ref a,ref b);4.3.2 方法的参数传递方法的参数传递l3输出参数输出参数l方法中的方法中的return语句只能返回一个运算结果,虽然也可以语句只能返回一个运算结果,虽然也可以使用引用型参数返回计算结果,但用使用引用型参数返回计算结果,但用ref修饰的参数在传参修饰的参数在传参前要求先初始化实参。但有时候参数在传参前无法确定其前要求先初始化实参。但有时候参数在传参前无法确定其值,其值应由方法调用结束后返回,所在在传参前确定其值,其值应由方法调用结束后返回,所在在传参前确定其值是没有意义的。这时可以使用输出参数,输出参数不需值是没有意义的。这时可以使用输出参数,输出参数不需要对实参进

46、行初始化,它专门用于把方法中的数据通过形要对实参进行初始化,它专门用于把方法中的数据通过形参返回给实参,但不会将实参的值传递给形参。一个方法参返回给实参,但不会将实参的值传递给形参。一个方法中可允许有多个输出参数。中可允许有多个输出参数。lC#通过通过out关键字来声明输出参数,无论是形参还是实参关键字来声明输出参数,无论是形参还是实参,只要是输出参数,都必须添加,只要是输出参数,都必须添加out关键字。关键字。4.3.2 方法的参数传递方法的参数传递l【实例【实例4-5】用输出参数求文件路径中的目录和文】用输出参数求文件路径中的目录和文件名。件名。4.3.2 方法的参数传递方法的参数传递l4

47、引用类型数据的传参引用类型数据的传参l引用类型参数总是按引用传递的,所以引用类型参数传递引用类型参数总是按引用传递的,所以引用类型参数传递不需要使用不需要使用ref或或out关键字关键字(string除外除外),引用类型参数的,引用类型参数的传递,实际上是将实参对数据的引用复制给了形参。所以传递,实际上是将实参对数据的引用复制给了形参。所以形参与实参共同指向同一个内存区域。形参与实参共同指向同一个内存区域。l【实例【实例4-6】用引用类型数据的传参修改对象值。】用引用类型数据的传参修改对象值。4.3.2 方法的参数传递方法的参数传递l5数组型参数数组型参数l数组也是引用类型数据,把数组作为参数

48、传递时,也数组也是引用类型数据,把数组作为参数传递时,也是引用传参。但把数组作为参数,有两种使用形式:是引用传参。但把数组作为参数,有两种使用形式:一种是在形参数组前不添加一种是在形参数组前不添加params修饰符,另一种是修饰符,另一种是在形参数组前添加在形参数组前添加params修饰符。不添加修饰符。不添加params修修饰符时,所对应的实参必须是一个数组名;添加饰符时,所对应的实参必须是一个数组名;添加params修饰符时,所对应的实参可以是数组名,也可修饰符时,所对应的实参可以是数组名,也可以是数组元素值的列表,此时,系统将自动把各种元以是数组元素值的列表,此时,系统将自动把各种元素值

49、组织到一个数组中。无论采用哪一种形式,形参素值组织到一个数组中。无论采用哪一种形式,形参数组都不能定义数组的长度。数组都不能定义数组的长度。4.3.2 方法的参数传递方法的参数传递l【实例【实例4-7】使用不添加】使用不添加params和添加和添加params修修改符的数组传参求数组中的最大值。改符的数组传参求数组中的最大值。4.3.3 方法的重载方法的重载l在编程时,一般是一个方法对应一种功能,但有时需要实在编程时,一般是一个方法对应一种功能,但有时需要实现同一类功能,只是有些细节不同。例如希望从几个数中现同一类功能,只是有些细节不同。例如希望从几个数中找出其中的最大者,而每次数据个数或类型

50、不同,如找出其中的最大者,而每次数据个数或类型不同,如2个整个整数,数,2个双精度数、个双精度数、3个整数、或一个整型数组做为参数。个整数、或一个整型数组做为参数。这时,我们可以设计出这时,我们可以设计出4个不同名的方法,其形式为:个不同名的方法,其形式为:public int MaxIntTwo(int a,int b)public double MaxDouble(double a,double b)public int MaxIntThree(int a,int b,int c)public int MaxArray(int a)l这时,程序者需要以不同的方法名来命名这些功能类似的这时,

51、程序者需要以不同的方法名来命名这些功能类似的方法,而调用者更需记住不同的方法名,不是很方便,在方法,而调用者更需记住不同的方法名,不是很方便,在C#中,允许用同一方法名定义多个方法,这些方法的参数中,允许用同一方法名定义多个方法,这些方法的参数个数或参数类型不同,这就是方法的重载个数或参数类型不同,这就是方法的重载(function overloading)。4.3.3 方法的重载方法的重载l方法重载有两点要求:方法重载有两点要求:(1)重载的方法名称必须相同;重载的方法名称必须相同;(2)重载方法的形参个数或类型必须不同,否则将出现一个重载方法的形参个数或类型必须不同,否则将出现一个“已定义

52、了一个具有相同参数类型的成员已定义了一个具有相同参数类型的成员”l如果要完成上例相似功能的如果要完成上例相似功能的4个方法,重载方法如下:个方法,重载方法如下:public int Max(int a,int b)public double Max(double a,double b)public int Max(int a,int b,int c)public int Max(int a)l在调用具有重载的方法时,系统会根据参数的类型或个数在调用具有重载的方法时,系统会根据参数的类型或个数确定最匹配的方法被调用。确定最匹配的方法被调用。4.3.3 方法的重载方法的重载l【实例【实例4-8】利

53、用方法重载实现】利用方法重载实现2个整数,个整数,2个双精个双精度数、度数、3个整数中求最大值。个整数中求最大值。4.4 构造函数构造函数l4.4.1 构造函数的声明和调用构造函数的声明和调用 l4.4.2 构造函数的重载构造函数的重载 l4.4.3 构造函数与只读字段构造函数与只读字段 l4.4.4 对象的生命周期和析构函数对象的生命周期和析构函数4.4.1 构造函数的声明和调用构造函数的声明和调用 l构造函数是类中的一种特殊的方法,其一般形式如下:构造函数是类中的一种特殊的方法,其一般形式如下:public 构造函数名构造函数名(参数列表参数列表)语句语句;l和普通方法相比,构造函数有两个

54、特别要求,一是构造函和普通方法相比,构造函数有两个特别要求,一是构造函数的名称必须和类名相同,二是构造函数不允许有返回类数的名称必须和类名相同,二是构造函数不允许有返回类型(包括型(包括void类型)。类型)。l其中,构造函数的参数列表可省略,也可以不包含任何语其中,构造函数的参数列表可省略,也可以不包含任何语句。不包含任何参数和语句的构造函数称为默认构造函数句。不包含任何参数和语句的构造函数称为默认构造函数。如果没有定义构造函数,编译器将自动生成默认构造函。如果没有定义构造函数,编译器将自动生成默认构造函数由,默认构造函数的形式如下:数由,默认构造函数的形式如下:public 构造函数名构造

55、函数名()4.4.2 构造函数的重载构造函数的重载l构造函数重载与方法一样可以重载。在一个类中,可以定义多构造函数重载与方法一样可以重载。在一个类中,可以定义多个构造函数,以便对对象提供不同的初始化方法,以满足创建个构造函数,以便对对象提供不同的初始化方法,以满足创建对象时的不同需要。例如,在创建一个对象时的不同需要。例如,在创建一个Student对象时,只想指对象时,只想指定定name的值,而的值,而age为默认的为默认的20。可以声明一个如下所示的构。可以声明一个如下所示的构造函数:造函数:lpublic Student(string name)this.name=name;this.ag

56、e=20;l该构造函数和以上面的该构造函数和以上面的public Student(string name,int age)构造函数相比,参数的个数不同,是一个合法的构造函数。此构造函数相比,参数的个数不同,是一个合法的构造函数。此时,可以声明一个只有一个实参的对象:时,可以声明一个只有一个实参的对象:Student stu=new Student(郭靖郭靖);4.4.2 构造函数的重载构造函数的重载l【实例【实例4-9】利用构造函数重载实现不同对象实例】利用构造函数重载实现不同对象实例化。化。4.4.3 构造函数与只读字段构造函数与只读字段lC#中类的字段成员可通过关键字中类的字段成员可通过关

57、键字readonly设置为设置为只读字段,对于标记为只读的字段来说,只有在只读字段,对于标记为只读的字段来说,只有在声明时为它赋值,或者在对象初始化时赋值。在声明时为它赋值,或者在对象初始化时赋值。在声明时为只读字段赋值与声明常量没有区别,在声明时为只读字段赋值与声明常量没有区别,在对象初始化时为只读字段赋值需要使用构造函数对象初始化时为只读字段赋值需要使用构造函数实现。实现。4.4.3 构造函数与只读字段构造函数与只读字段l【实例【实例4-10】公园门票调价问题】公园门票调价问题。4.4.4 对象的生命周期和析构函数对象的生命周期和析构函数 lC#程序中,一个对象是类的一个实例,实际上就是一

58、个引程序中,一个对象是类的一个实例,实际上就是一个引用型的变量,在程序运行过程中,它需要占用一定的内存用型的变量,在程序运行过程中,它需要占用一定的内存空间,空间,.NET 的公共语言运行时负责为其分配内存。当程序的公共语言运行时负责为其分配内存。当程序运行结束后,需要回收它所占用的内存空间。运行结束后,需要回收它所占用的内存空间。l正如前面的介绍一样,正如前面的介绍一样,.NET的公共语言运行时把值类型变的公共语言运行时把值类型变量和引用型变量放在不同的内存区域中管理。量和引用型变量放在不同的内存区域中管理。l值类型变量使用值类型变量使用“栈栈”来管理,栈是一种按照来管理,栈是一种按照“先进

59、后出先进后出”方式存取的内存区域。当方法被调用时,方法内的值类方式存取的内存区域。当方法被调用时,方法内的值类型变量(包括形参变量)自动获得内存,当方法调用结束型变量(包括形参变量)自动获得内存,当方法调用结束时,这些变量所占用的内存将自动释放。时,这些变量所占用的内存将自动释放。4.4.4 对象的生命周期和析构函数对象的生命周期和析构函数l引用型变量使用引用型变量使用“堆堆”来管理,堆是分配对象时所使用的来管理,堆是分配对象时所使用的内存区域。在方法调用过程中,一旦使用运算符内存区域。在方法调用过程中,一旦使用运算符new创建创建了对象,了对象,.NET的公共语言运行时立即为该对象从堆中分配

60、的公共语言运行时立即为该对象从堆中分配内存。内存。l当方法调用结束时,对象所占用的内存并不会自动从堆中当方法调用结束时,对象所占用的内存并不会自动从堆中释放。在释放。在.NET中,对象所占用的内存只能由中,对象所占用的内存只能由.NET的公共语的公共语言运行时的垃圾回收器来回收,垃圾回收器没有预定的工言运行时的垃圾回收器来回收,垃圾回收器没有预定的工作模式,其工作时间间隔是不可预知的,垃圾回收器的优作模式,其工作时间间隔是不可预知的,垃圾回收器的优化引擎能根据分配情况确定回收的最佳时机。化引擎能根据分配情况确定回收的最佳时机。4.4.4 对象的生命周期和析构函数对象的生命周期和析构函数l一个对

61、象的生命周期可分为以下几个阶段:一个对象的生命周期可分为以下几个阶段:l(1)使用使用new运算符创建对象并要求获得内存;运算符创建对象并要求获得内存;l(2)对象初始化,包括对象的数据成员的初始化;对象初始化,包括对象的数据成员的初始化;l(3)使用对象,包括访问对象的数据成员、调用对象的方法使用对象,包括访问对象的数据成员、调用对象的方法成员;成员;l(4)对象释放前释放对象所占用的资源,如关闭磁盘文件、对象释放前释放对象所占用的资源,如关闭磁盘文件、网络连接等;网络连接等;l(5)释放对象,回收内存(由垃圾回收器自动完成)。释放对象,回收内存(由垃圾回收器自动完成)。l其中,第其中,第2

62、阶段可通过调用对象的构造函数来完成,第阶段可通过调用对象的构造函数来完成,第4阶阶段可通过析构函数来完成。段可通过析构函数来完成。4.4.4 对象的生命周期和析构函数对象的生命周期和析构函数lC#类的析构函数具有如下特点:类的析构函数具有如下特点:l(1)不能在结构中定义析构函数,只能对类使用析构函数;不能在结构中定义析构函数,只能对类使用析构函数;l(2)一个类只能有一个析构函数;一个类只能有一个析构函数;l(3)无法继承或重载析构函数;无法继承或重载析构函数;l(4)析构函数既没有修饰符,也没有参数;析构函数既没有修饰符,也没有参数;l(5)在析构函数被调用时,在析构函数被调用时,.NET

63、的公共语言运行时自动添的公共语言运行时自动添加对基类加对基类Object.Finalize方法的调用,以清理现场,因此方法的调用,以清理现场,因此在析构函数中不能包含对在析构函数中不能包含对Object.Finalize方法的调用。方法的调用。4.4.4 对象的生命周期和析构函数对象的生命周期和析构函数l析构函数的一般形式如下:析构函数的一般形式如下:函数名函数名()语句语句;l在默认情况下,编译器自动生成空的析构函数,因此在默认情况下,编译器自动生成空的析构函数,因此C#不不允许定义空的析构函数。其实析构函数性能较差,并不推允许定义空的析构函数。其实析构函数性能较差,并不推荐值使用,如果需要尽快关闭和释放所占用的资源,应实荐值使用,如果需要尽快关闭和释放所占用的资源,应实现一个强制回收方法,一般称为现一个强制回收方法,一般称为close()或或Dispose()。2022-11-15612022-11-1562

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!