C程序设计课件(资料全集)c6.ppt
《C程序设计课件(资料全集)c6.ppt》由会员分享,可在线阅读,更多相关《C程序设计课件(资料全集)c6.ppt(55页珍藏版)》请在三一办公上搜索。
1、第六章 面向对象程序设计,C#.net程序设计,本章主要内容,对象、类和结构方法,方法的参数(值类型,引用类型,参数数组params)静态类与静态成员属性与索引器继承(多态性,new,Virtual和Override关键字),接口继承abstract抽象类和类成员和sealed密封类和类成员重载运算符使用Visual Studio类关系图可视化创建对象,对象、类和结构概述,对象、类和结构具有以下特点:新数据类型是使用类和结构定义的。对象是给定数据类型(类和结构)的实例。在执行应用程序时,数据类型为创建对象(或实例化)提供蓝图。C#应用程序始终包含至少一个类。结构可视为轻量类,是创建用于存储少量
2、数据的数据类型的理想选择,不能通过继承进行扩展的类型。类支持继承,这意味着它们可以从先前定义的类中派生。典型的 C#应用程序由自定义的类和.NET框架 的类组成。类是 C#中功能最为强大的数据类型。类定义了数据类型的数据和行为。,对象、类和结构,结构(struct),结构与类一样都具有表示其数据和行为的成员。这些成员包括:字段,属性,方法,事件,运算符,索引器,构造函数,析构函数和嵌套类型。结构与类共享几乎所有相同的语法,但结构比类受到的限制更多。结构有以下特点:结构是值类型,而类是引用类型。如果从结构创建一个对象并将该对象赋给某个变量,变量则包含结构的全部值。复制包含结构的变量时,将复制所有
3、数据,对新副本所做的任何修改都不会改变旧副本的数据。尽管结构的静态字段可以初始化,结构实例字段声明还是不能使用初始值设定项。结构不能声明默认构造函数(没有参数的构造函数)或析构函数。与类不同,结构的实例化可以不使用 new 运算符。一个结构不能从另一个结构或类继承,而且不能作为一个类的基。所有结构都直接继承自 System.ValueType,后者继承自 System.Object。结构可以实现接口。由于结构不使用引用,因此结构没有标识,具有相同数据的两个值类型实例是无法区分的。,对象、类和结构,对象,对象指的是一个实体的实例,在这个实体中包括了特定的属性数据和对这些数据进行操作的方法。对象具
4、有以下特点:C#中使用的全都是对象,包括 Windows 窗体和控件。对象是实例化的;也就是说,对象是从类和结构所定义的模板中创建的。对象使用属性获取和更改它们所包含的信息。对象通常具有允许它们执行操作的方法和事件。Visual Studio 提供了操作对象的工具:使用“属性”窗口可以更改对象(如 Windows 窗体)的属性。使用对象浏览器可以检查对象的内容。所有 C#对象都继承自object。,对象、类和结构,类声明,类是使用class关键字来定义的,类声明语句定义一个新类,其语法格式为:特征 修饰符 class 类名:基类名和任何实现接口的列表类体类的主要修饰符有以下几种之一。publi
5、c 表示不限制对该类的访问protected 表示只能从所在类和所在类派生的子类进行访问private只有其所在类才能访问abstract 抽象类不允许建立类的实例internal 只有在同一程序集(.exe 或.dll)的文件中的类型或成员才可访问的partial 表示将类的定义拆分到两个或多个源文件中默认情况下,在命名空间中或在编译单元顶部(例如,不在命名空间、类或结构中)声明的任何类型都是internal。下面是声明类Shape的代码:,对象、类和结构,abstract class Shape/抽象基类,不可实例化public const double pi=System.Math.PI
6、;/常量protected double x,y;/受保护,可继承变量public Shape()/默认构造函数x=y=0;public Shape(double x,double y)/带参数构造函数this.x=x;this.y=y;public abstract double Area();/抽象方法,需重载在该例中 abstract class Shape类定义使用了修饰符abstract,这表示该类是抽象基类,不可实例化。类的名称位于 class 关键字的后面,就是Shape。Shape类定义的其余部分是类的主体,用于定义行为和数据。类的字段、属性、方法和事件统称为“类成员”。,分部
7、类定义,可以将类、结构或接口的定义拆分到两个或多个源文件中。每个源文件包含类定义的一部分,编译应用程序时将把所有部分组合起来。拆分类定义,使用 partial 关键字修饰符,partial 修饰符只能出现在紧靠关键字 class、struct 或 interface 前面的位置。如下例所示。Visual Studio 在创建 Windows 窗体使用此分部定义方法,例如:下面在form1.cs和Form1.Designer.cs代码文件中使用分部定义共同定义类Form1。其中Form1.Designer.cs是窗体设计器自动生成的源代码,而form1.cs是手工编程代码的文件。public p
8、artial class Form1:Form/form1.cs 文件partial class Form1/Form1.Designer.cs,对象、类和结构,类继承定义,继承是类的重要特性。类可以从其他类中继承。在声明类时,在类名称后放置一个冒号,然后在冒号后指定要从中继承的类(即基类)。例如定义一个继承了Shape类的Ellipse类:class Ellipse:Shape public Ellipse(double x,double y):base(x,y)/使用基类Shape的构造函数 public override double Area()/函数重载 return pi*x*y;
9、使用继承定义的类称为用派生类,派生类的成员包括基类的所有非私有数据和行为以及派生类为自己定义的其他数据或行为。派生类将无法继承基类私有的成员。例如:派生类Ellipse继承基类Shape的公有的常量pi和受保护的字段x,y。,对象、类和结构,字段,类的字段存储类要满足其设计所需要的数据。声明字段时可以使用赋值运算符为字段指定一个初始值。字段恰好在创建对象实例调用构造函数之前初始化。字段初始值设定项不能引用其他实例字段。字段可标记为public、private、protected、internal。这些修饰符定义类的使用者访问字段的方式。可以选择将字段声明为static静态,这使得在没有创建实例
10、能调用静态字段。常数被声明为字段,声明时在字段的类型前面使用const关键字。常数必须在声明时初始化。例如:public const double pi=System.Math.PI;只读字段将字段声明为readonly。只读字段只能在初始化期间或在构造函数中赋值。为了简单起见,下面示例使用public字段,这样可以直接获取或设置字段值,但是不建议这样做。字段通常应为private。外部类应当通过方法、属性或索引器来间接访问字段。例如:,对象、类和结构,字段,public class Point public double x,y;/声明字段 public double z=0;/声明字段具有
11、初始值。public readonly string name=Point;/声明具有初始值只读字段。public Point(double x,double y)/构造函数用于初始化字段。this.x=x;this.y=y;name=string.Format(0(1,2,3),name,x,y,z);public Point():this(0,0)/调用其他构造函数,对象、类和结构,构造函数,构造函数是在创建给定类型的对象时执行的类的方法。构造函数具有与类或结构相同的名称,它通常用于初始化新对象的数据成员。只要创建类或结构,就会调用它的构造函数。类或结构可能有多个接受不同参数的构造函数。在
12、上面的示例中,定义了一个具有一个简单的构造函数名为Point的类。类定义对象的类型,但它不是对象本身。对象是基于类的具体实体,有时称为类的实例。通过使用 new 关键字,后跟类的构造函数,可以创建对象,在为新对象分配内存之后,new 运算符立即调用构造函数。下面的TestPoint类Main()中使用 new 运算符创建对象来实例化Point类:class TestPoint static void Main()Point p=new Point(1.0,3.0);/创建Point对象实例p p.z=1;/Point对象实例p的z字段赋值 Console.WriteLine(x,y,z)=0,
13、1,2,3,p.x,p.y,p.z,p.name);,对象、类和结构,构造函数,不带参数的构造函数称为“默认构造函数”。当类没有构造函数,系统自动生成一个构造函数,并且将用默认值来初始化对象字段,有关默认值参见表2.1。构造函数可以使用 this 关键字调用同一类中的另一构造函数。如public Point():this(0,0)/调用其他构造函数基类的构造函数将在其派生类构造函数调用前调用,使用:base(x,y)表示调用基类的构造函数。在前面示例中,抽象基类Shape的构造函数在执行派生类Ellipse构造函数块之前被调用,使用:base(x,y)表示调用基类Shape的构造函数。publ
14、ic Ellipse(double x,double y):base(x,y)/使用基类Shape的构造函数在派生类中,如果不使用base关键字来显式调用基类构造函数,则将隐式调用默认构造函数(如果有的话)。这意味着下面的构造函数隐式调用基类Shape默认构造函数:public Ellipse(double x,double y)/隐式调用基类Shape的构造函数:base()如果基类没有提供默认构造函数,派生类必须使用 base 显式调用基构造函数。如没有默认构造函数,前面不使用base 关键字的派生类构造函数将无法编译。,对象、类和结构,析构函数,在类的实例超出范围时,类的实例将会自动执行
15、析构函数。例如:Shape()/析构函数,对象销毁时的清除语句.Console.WriteLine(调用Shape析构函数(0,1),x,y);Ellipse()/析构函数 Console.WriteLine(调用Ellipse析构函数(0,1,Area2:f),x,y,Area();析构函数特点:一个类只能有一个析构函数。无法继承或重载析构函数。无法调用析构函数。它们是被自动调用的。析构函数既没有修饰符,也没有参数。可以通过调用GC.Collect()强制进行垃圾回收,但大多数情况下应避免这样做,因为这样会导致性能问题。调用对象结束将按照从派生程度最大的到派生程度最小的次序调用析构函数。,对
16、象、类和结构,方法声明,方法是包含一系列语句的代码块,是类或结构中用于执行计算或其它行为的成员。在 C#中,每个执行指令都是在方法中完成的。方法在类或结构中声明,声明时需要指定访问级别、返回值、方法名称以及任何方法参数。方法参数放在括号中,并用逗号隔开。空括号表示方法不需要参数。方法的声明格式:特征 修饰符 方法名称(形式化参数表)方法体 方法的修饰符可以是(public,protected,internal,private,static,abstract,virtual,override等)及其组合。例如下面例子的Area方法:Shape类:public abstract double Ar
17、ea();/抽象方法,需要在派生类重载该方法Ellipse类:public override double Area()/派生类重载基类抽象,方法,方法的参数,C#中方法的参数有以下两种类型:值传递类型参数:不含任何修饰符。如:void SquareIt(int x)引用传递类型参数:以ref 或out 修饰符声明。如:void SquareIt(ref int x)方法值传递类型参数意味着向方法传递变量的一个副本。方法内发生的参数更改对该变量中存储的原始数据无任何影响。而引用传递类型参数意味所调用的方法可更改参数的原始数据值。向方法传递结构和类引用之间的区别:向方法传递结构时,传递的是该结构
18、的副本,而在传递类实例时,传递的是一个引用。传递类型参数修饰符out与ref 的区别在于:传递到 ref的参数必须先初始化。而out 的参数在传递之前不需要显式初始化。值传递有以下两种类型:值传递值类型,如:void SquareIt(int x)参数int x 是值类型。值传递引用类型,如:void Change(int pArray)数组pArray 为引用类型。引用传递有以下两种类型:引用传递值类型,如:void SquareIt(ref int x)引用传递引用类型,如:void Change(ref int pArray),方法,值传递值类型参数示例(ParamSample项目代码)
19、:class PassingValByVal static void SquareIt(int x)x*=x;System.Console.WriteLine(SquareIt方法内的n值:0,x);static void Main()int n=5;System.Console.WriteLine(调用SquareIt方法前的n值:0,n);SquareIt(n);/通过值来传递值 System.Console.WriteLine(调用SquareIt方法后的n值:0,n);该程序运行输出:调用SquareIt方法前的n值:5 SquareIt方法内的n值:25 调用SquareIt方法后的
20、n值:5 在这例子里,变量 n 为值类型,包含数据(值为 5)。当调用 SquareIt 时,n 的内容被复制到参数 x 中,在方法内将该参数求平方。但在 Main 中,n 的值在调用 SquareIt 方法前后是相同的。实际上,方法内发生的更改只影响局部变量 x。,值传递引用类型例子:class PassingRefByVal static void Change(int pArray)pArray0=888;/将pArray的第一个元素赋值为888,改变arr0 pArray=new int5-3,-1,-2,-3,-4;/引用新的数组,不改变arr System.Console.Writ
21、eLine(方法内的数组第一元素:0,pArray0);static void Main()int arr=1,4,5;System.Console.WriteLine(调用方法前的数组第一元素:0,arr0);Change(arr);System.Console.WriteLine(调用方法后的数组第一元素:0,arr0);在上个示例中,数组 arr 为引用类型,在未使用 ref 参数的情况下传递给方法。在此情况下,将向Change方法传递指向 arr 的引用的一个副本。Change方法有可能更改数组元素的内容,输出显示arr0 从 1 改为 888。但是,在 Change 方法内使用 ne
22、w 运算符来分配新的内存部分,将使变量 pArray 引用新的数组。因此,这之后的任何更改都不会影响原始数组 arr(它是在 Main 内创建的)。,该程序运行输出:调用方法前的数组第一元素:1方法内的数组第一元素:-3调用方法后的数组第一元素:888,引用传递值类型示例 class PassingValByRef/参数X的值通过关键字ref来传递,改变x的值,将会改变输入的x的值 static void SquareIt(ref int x)x*=x;System.Console.WriteLine(SquareIt方法内的n值:0,x);static void Main()int n=5;
23、System.Console.WriteLine(调用SquareIt方法前的n值:0,n);SquareIt(ref n);/通过ref关键字来传递变量引用.System.Console.WriteLine(调用SquareIt方法后的n值:0,n);该程序运行输出:调用SquareIt方法前的n值:5 SquareIt方法内的n值:25 调用SquareIt方法后的n值:25 本示例中,传递的不是 n 的值,而是对 n 的引用。参数 x 不是 int 类型,它是对 int 的引用(本例中为对 n 的引用)。因此,当在方法内对 x 求平方时,实际被求平方的是 x 所引用的项:n。,引用传递引
24、用类型示例:class PassingRefByRef static void Change(ref int pArray)/下面两个数组赋值都将改变原始的元素 pArray0=888;/将pArray的第一个元素赋值为 pArray=new int5-3,-1,-2,-3,-4;/pArray 引用新的数组 System.Console.WriteLine(Change方法内的数组第一元素:0,pArray0);static void Main()int arr=1,4,5;System.Console.WriteLine(调用Change方法前的数组第一元素:0,arr0);Change(
25、ref arr);/通过ref关键字来传递数组引用 System.Console.WriteLine(调用Change方法后的数组第一元素:0,arr0);该程序运行输出:调用Change方法前的数组第一元素:1Change方法内的数组第一元素:-3调用Change方法后的数组第一元素:-3本示例中Change方法内发生的所有更改都影响 Main 中的原始数组。实际上,使用 new 运算符对原始数组进行了重新分配。因此,调用 Change 方法后,对 arr 的任何引用都将指向 Change 方法中创建的五个元素的数组。,参数数组params当方法的参数数量不确定时,可以考虑使用参数数组par
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 程序设计 课件 资料 全集 c6

链接地址:https://www.31ppt.com/p-5373682.html