《C#程序设计教程 教学课件 ppt 作者 刘瑞新第4章 面向对象的程序设计方法》由会员分享,可在线阅读,更多相关《C#程序设计教程 教学课件 ppt 作者 刘瑞新第4章 面向对象的程序设计方法(29页珍藏版)》请在金锄头文库上搜索。
1、第4章 面向对象的程序设计方法,本章讲述的主要内容 4.1 面向对象程序设计的概念 4.2 创建自定义类 4.3 在应用程序中使用自定义类 4.4 类的继承 4.5 类的多态性,4.1 面向对象程序设计的概念,4.1.1 面向对象与传统编程方法的不同 1. 传统程序设计方法的设计思路 例如,设计一个用户登录程序时,面向过程的程序设计思路如下: 1) 创建一个提供用户输入用户名和密码的应用程序界面。 2) 用户提交数据后首先判断用户名和密码是否为空,若为空提示出错,否则继续。 3) 判断用户输入的用户名是否为合法用户名。是,则继续,否则提示用户名错。 4) 判断用户输入的密码是否与输入的用户名匹
2、配。是,则登录成功,否则提示密码错。 可以看出整个程序设计思路是按照事情的发展进行的,也就是围绕着事情发展的过程进行的。,4.1 面向对象程序设计的概念,4.1.1 面向对象与传统编程方法的不同 2.面向对象设计方法的设计思路 面向对象的程序设计方法模拟人类认识世界的思想方法,将所有实体看作一个对象。仍然是上面的例子,面向对象的程序设计思路如下: 1) 同样,首先需要创建一个提供用户输入用户名和密码的 应用程序界面。 2) 将用户看作一个对象。 3) 用户对象拥有一个用于检查用户名和密码合法性的方法。 4) 用户提交数据后,调用方法对数据进行检验,并根据检验返回结果确定用户登录是否成功。,4.
3、1 面向对象程序设计的概念,4.1.1 面向对象与传统编程方法的不同 3. 面向对象程序设计方法的优点 首先,上述两种方法都能完成用户登录程序的设计,但采用面向对象的程序设计方法具有如下一些优点。 (1) 可扩展性 在传统的设计方法中功能的实现分散在了很多步骤中,对功能的扩展极为不利。而在面向对象的设计中,功能靠方法来实现,需要新功能时只需要创建新的方法即可,保证了面向对象设计的可扩展性。 (2) 分工明确 面向对象的设计方法中将所有问题都划分成相应的对象,程序功能依靠方法来实现,从而使程序各部分有了明确的分工。当因对象发生变化需要修改程序时,可通过较小的局部改动来完成新的需求,保证了程序具有
4、良好的可移植性。,4.1 面向对象程序设计的概念,4.1.1 面向对象与传统编程方法的不同 4. 面向对象程序设计的基本步骤 前面介绍过,在Visual Studio中进行简单应用程序设计时的主要步骤为: 需求分析设计程序界面设置控件对象属性编写实现功能及控制界面的代码 使用面向对象技术进行程序设计时的基本步骤为: 1) 需求分析。 2) 创建一个或多个需要的类,声明其属性和方法。 3) 设计程序界面(用户操作界面)。 4) 在事件处理程序中对类进行实例化得到相应的对象,通过操作对象的属性,调用对象的方法来实现设计目标。,4.1 面向对象程序设计的概念,4.1.2 类和对象 2. 面向对象的三
5、个重要特征 (1) 封装性 开发人员并不需要完全了解类体内每句代码的具体含义,只需通过对象来调用类内某个属性和方法即可实现需要的功能,这就是类的封装性。 (2) 继承性 一个类可以拥有它继承的类的所有成员,而不需要重新定义,这种特性在面向对象编程技术中称作对象的“继承性。 (3) 多态性 多态性是指在基类中定义的属性或方法被派生类继承后可以进行更改。,4.1 面向对象程序设计的概念,4.1.3 类成员的基本概念 1. 字段 2. 属性 3. 方法 4. 构造函数与析构函数,4.2 创建自定义类,4.2.1 创建类 其语法格式为: 访问修饰符 class 类名 : 基类名或接口序列 字段成员 属
6、性成员 方法成员 事件成员 构造函数 析构函数 ,4.2 创建自定义类,4.2.1 创建类 1. 声明类字段 字段的声明格式与普通变量的声明格式相同。在类体中,字段声明的位置没有特殊要求,习惯上将字段声明在类体中的最前面,以便于阅读。例如: class Student /定义一个Student类 private string stuname; /定义类的3个字段变量) private string stuclass; private float stugrade; ,4.2 创建自定义类,4.2.1 创建类 2. 声明类属性 访问修饰符 类型 属性名 get ; return 类变量; set
7、 ; 类变量 = value; ,4.2 创建自定义类,4.2.1 创建类 3. 使用访问修饰符 访问修饰符确定了在什么范围中的对象可以访问类成员。访问修饰符的规定与声明类时使用的修饰符含义相同。 在类定义中,如果声明的属性、方法、事件等没有使用任何访问修饰符,则该成员被认为是私有的(private)。如果不涉及继承,private与protected没有什么区别。如果成员被声明为private或protected,则不允许在类定义外使用点运算符访问。 在一个类定义中,通常字段被声明为private或protected,这样在类定义外将无法看到字段成员,这就是所谓“数据隐藏”。其他成员通常被声
8、明为public,以便通过这些成员实现对类的字段成员的操作,类定义中的属性用于完成最基本的,对字段的读写操作。,4.2 创建自定义类,4.2.2 类的方法与重载 1. 定义类的方法 在类中创建方法的语法格式为: 访问修饰符 返回值类型 方法名(传递参数列表) ; /方法体语句块 return 变量; ,4.2 创建自定义类,4.2.2 类的方法与重载 2. 方法的重载 有时方法实现的功能需要针对多种类型的参数,虽然C#有隐式转换功能,但这种转换在有些情况下会导致运算结果的错误,而有时数据类型无法实现隐式转换甚至根本无法转换。有时方法实现的功能需要处理的数据个数不同,这时会因为传递实参的个数不同
9、而导致方法调用的失败。例如:前面例子中的整型数据交换方法只能实现两个整型变量的值交换,无法通过隐式或显式转换来实现其他类型变量的值交换。如果在调用方法时传递的是两个浮点型变量,则运行程序时,将出现编译错误。 为解决上述问题,C#允许在同一个类中声明多个具有不同参数集(不同参数数量、不同参数数据类型、不同参数顺序)的同名方法,调用方法时C#编译器能根据调用语句传递过来的参数的具体情况自动选择相应的方法,这种处理方式称为“方法重载”。,4.2 创建自定义类,4.2.2 类的方法与重载 2. 方法的重载 C#允许在同一个类中声明多个具有不同参数集(不同参数数量、不同参数数据类型、不同参数顺序)的同名
10、方法,调用方法时C#编译器能根据调用语句传递过来的参数的具体情况自动选择相应的方法,这种处理方式称为“方法重载”。 使用方法重载时需要注意如下两点要求: 1) 重载的方法名称必须相同。 2) 重载的方法,其形参个数或类型必须不同,否则将出现“已经定义了一个具有相同类型参数的方法成员”的编译错误。,4.2 创建自定义类,4.2.3 方法参数的传递方式 1值参数 值参数是指声明时不带任何修饰符的参数。当使用值类型的参数调用方法时,编译程序将实参的值做一份副本,并且把此副本传递给该方法的相应形参。被调用的方法不会修改内存中实参的值,所以使用值参数时,可以保证实参值是安全的。 2引用参数 在参数前加上
11、ref修饰符声明的参数为引用参数。值类型参数传递的是实参值的副本,而引用型参数向方法传递的是实参的地址,使得实参的存储位置与形参的存储位置相同。在C#中,调用带引用型参数的方法就可以在该方法的内部改变调用方法的实参数值了。,4.2 创建自定义类,4.2.4 构造与析构函数 1. 构造函数 构造函数实际上是一种特殊的方法,每次创建类的实例时都会调用它,构造函数的主要作用就是自动初始化成员变量。一般情况下不需要为类定义相关的构造函数,因为基类(Object类)提供了一个默认的实现方式。只有在创建类对象的同时为对象设置一些初始状态时才需要声明自定义的构造函数。定义构造函数的语法格式为: 访问修饰符
12、类名(参数列表) /构造函数的主体 ,4.2 创建自定义类,4.2.4 构造与析构函数 2. 析构函数 析构函数也是一种特殊的方法,主要用来在销毁类的实例时,自动完成内存清理工作,又称为垃圾收集器 一般来说,对象的生命周期从构造函数开始,以析构函数结束。在创建类的实例时,需要调用构造函数为其分配内存,而当类的实例的生命周期结束前,还必须释放它所占有的内存空间。在一个类中可能有许多对象,每个对象的生命期结束时,都要调用一次析构函数。 需要说明的是,在C#程序中有析构函数的对象占用的资源较多,在内存中驻留时间较长,在垃圾回收器检查到时并不会被销毁,并且还会调用专门的进程负责,从而消耗了更多的系统资
13、源。因此析构函数不能滥用,建议只有在必须时才使用析构函数。,4.2 创建自定义类,4.2.5 类的静态成员 在类成员定义中使用static修饰符表示的类成员称为类的“静态成员”。类的静态成员可以是静态字段、静态属性或静态方法。 静态成员属于整个类,所以对静态成员的访问不需要有类的对象实例存在,可直接通过类名称访问。 访问静态成员的语法格式为: 类名称.成员名称 由于静态成员属于整个类,所以在任何地方修改这些成员都将体现在该类的所有实例对象中,包括已经存在和新创建的类对象。同样,类的静态属性只能访问静态字段和静态方法,静态方法也只能访问类的静态字段和静态属性,这是因为非静态的属性和方法都有一个隐
14、式的this成员存在,对于静态属性和静态方法则不存在这个this成员。,4.3 在应用程序中使用自定义类,4.3.1 声明和访问类的对象 声明类的对象,也称为“类的实例化”,其声明方法与声明基本数据类型的方法基本相同,语法格式为: 类名 对象名 = new 类名(); 例如下列代码声明了一个Student类的stu对象 Student stu = new Student(); 由于静态成员属于整个类,所以在任何地方修改这些成员都将体现在该类的所有实例对象中,包括已经存在和新创建的类对象。同样,类的静态属性只能访问静态字段和静态方法,静态方法也只能访问类的静态字段和静态属性,这是因为非静态的属性
15、和方法都有一个隐式的this成员存在,对于静态属性和静态方法则不存在这个this成员。,4.3 在应用程序中使用自定义类,4.3.1 声明和访问类的对象 访问对象就是访问对象成员,即在应用程序中使用由类创建的对象,其代码编写格式与访问一般常用对象的代码格式完全相同。例如: Student stu = new Student(); stu.StuName =“张三“; /访问对象的属性 stu.StuClass = “网络0901“; int var1 = 78; int var2 =66; /调对象的GradeSum方法,并传2个参数,返回值存在sum中 int sum = stu.Grade
16、Sum(var1, var2);,4.3 在应用程序中使用自定义类,4.3.2 向项目中添加类项和类库 1. 添加类项(类文件),4.3 在应用程序中使用自定义类,4.3.2 向项目中添加类项和类库 2. 添加类库,4.4 类的继承,4.4.1 基类和派生类 1. 继承的基本规则 类的继承性具有以下一些规则: 1) 继承的单一性。派生类只能继承一个基类。 2) 继承是可传递的。例如,彩色电视从黑白电视中派生,液晶电视又从彩色电视中派生,那么液晶电视不仅继承了彩色电视中的成员,同样也继承了黑白电视中的成员。 3) 派生类应当是对基类的扩展。派生类可以添加新的成员,但不能除去已经继承的成员的定义。 4) 派生类可以重写基类的成员。 5) 构造函数和析构函数不能被继承。调用带参数的基类构造函数时应使用base关键字。,4.4 类的继承,4.4.1 基类和派生类 1. 继承的基本规则 类的继承性具有以下一些规则: 1) 继承的单一性。派生类只能继承一个基类。 2) 继承