C#程序设计-第三章ppt课件.ppt

上传人(卖家):三亚风情 文档编号:2921299 上传时间:2022-06-11 格式:PPT 页数:85 大小:438.50KB
下载 相关 举报
C#程序设计-第三章ppt课件.ppt_第1页
第1页 / 共85页
C#程序设计-第三章ppt课件.ppt_第2页
第2页 / 共85页
C#程序设计-第三章ppt课件.ppt_第3页
第3页 / 共85页
C#程序设计-第三章ppt课件.ppt_第4页
第4页 / 共85页
C#程序设计-第三章ppt课件.ppt_第5页
第5页 / 共85页
点击查看更多>>
资源描述

1、第三章 C#面向对象编程面向对象的概念C#类的声明与实例化C#类成员(方法成员、属性成员等)C#类的继承(派生类)C#类的多态C#接口C#结构面向对象的基本概念在面向过程编程方法(如C语言)基础上提出的一种新的编程方法,它将数据以及处理这些数据的代码封装在一起,实现了数据与代码的有机结合 (C+、C#)。对象是程序中最基本的运行实体对象中封装了描述该对象的数据和处理这些数据的方法,对象中的数据也称为属性,用于描述对象的状态,对象的方法则用于改变对象的状态 类(class)为属于某种类型的所有对象提供了统一的抽象描述,是对象的模板,对象是类的具体化,是类的实例。类必须要实例化后才能够操作 面向对

2、象程序设计的特征面向对象程序设计主要特征封装:将对象的数据和代码组合在一起形成统一的接口。外部代码不能直接访问封装在内部的数据,只能通过公共接口进行访问继承:由已有类派生新类,新类(子类、派生类)继承父类(基类)的数据和方法。形成了类的树形层次结构 多态:同名的方法可在不同的类中具有不同的表现行为 C#类的定义(申明)C#类采用关键词class定义申明类 类修饰符 class 类名称:基类类名称,接口列表 类成员修饰符 类的成员;类的修饰符:说明其他类对类成员的访问权限和类本身的特性(如:能不能被其他类继承)类名称:符合C#标识符的要求基类类名称和接口列表:说明该类是由哪个基类和哪些接口派生而

3、来(只允许1个基类,但是允许多个接口)。如果没有指定基类或接口,则默认其基类为object类类成员修饰符:说明类某个成员的访问权限等类成员:包括字段、属性、方法、事件、运算符等C#类的成员类的成员说明常数专属于某类的常量字段存储类的数据,也称为域、数据成员或成员变量属性类中可以像字段一样被访问的方法,实际上是通过特定的方法访问类中封装的字段方法定义类可以执行的操作,相当于类的成员函数事件有关事件发生时如何通知对象,如按钮对象的单击事件等索引器以类似于数组下标访问方法访问对象运算符对类的成员进行运算的符号构造函数创建类对象时被调用的特殊方法,用于初始化类对象。析构函数对象被销毁前被调用的特殊方法

4、。类申明示例及说明类的成员变量与普通变量定义方法相同。类的成员方法与C语言的函数声明类似C#的类既可以单独申明(定义) ,也可以申明在另外一个类的内部,支持嵌套申明C#允许将一个类的申明拆分到多个文件中,称为分部类,以partial关键词修饰(窗口程序设计时,窗口类都是分部类)类的嵌套声明 class A/外层类 class B/内层类 B类成员; A类成员;class Vehicle int color;/颜色 byte wheels;/车轮数量 float weight;/载重量 float speed;/速度 void Run()/运行 void Stop()/停止类的实例化类的实例化是

5、由类创建具体的对象。除了静态方法外,其它成员都需要通过有类创建的对象进行访问类属于引用类型,仅定义对象变量还不能使用,必须利用new关键词在堆中申请内存以保存对象实例才行可以如下形式访问类的成员除静态成员外:对象名称.成员 静态成员: 类名称.成员Vehicle v1;/v1不能直接使用 v1 = new Vehicle();/括号内有时有参数,由类的构造函数确定v1. wheels =3;/ Vehicle类声明时没有加成员修饰符,默认为private,这样访问实际上是不行类的修饰符控制其他类对本类的访问权限public:该类是公有类,对该类的访问不受限制。用于嵌套类的声明时,表示不限制对内

6、层类的访问。protected:该类是保护类,可以在外层类及外层类的子类中使用内层类(仅用于嵌套类的声明)private:该类是私有类,只能在外层类中使用该内层类(仅用于嵌套类的声明)(内层类的默认修饰符)internal:该类是内部类,允许同一程序集中的所有程序使用,不能由程序集之外的程序使用(外层类的默认修饰符) 说明类本身特性abstract:该类是抽象类,不能被实例化,只能用作基类sealed:该类是密封类,不能再作为基类派生出其它的类new:该类隐藏了外层类的同名成员,仅用于嵌套类声明static:该类是静态类,不需实例化类成员的修饰符之一类成员修饰符含义public公有成员,可以从

7、类的外部访问protected保护成员,只能由类或类的派生类访问private私有成员,只能由类本身访问。是类成员的默认修饰符 internal允许同一程序集中的类访问protected internal允许同一程序集中的所有类及其子类访问static静态成员,只能通过类名称访问,而不能通过对象实例访问readonly表示一个只读字段。除了赋初值外,不能改变其内容const常量成员,内容保持不变的数据成员new隐藏继承自基类的同名字段或方法virtual表示一个虚拟方法。该方法可以在派生类中实现abstract该方法仅定义了方法名称及执行方式而没有具体实现代码,包含了abstract方法的类是

8、抽象类,需要在派生类中实现类成员的修饰符之二类成员修饰符含义override表示该方法是从基类继承的virtual方法的实现sealed表示一个密封方法,不能在派生类中重写该方法,必须与override同时使用extern表示一个外部方法,其实现代码在类的外部访问权限修饰符public、private、protected、internal、 protected internal静态成员修饰符static字段或方法修饰符const 、readonly、virtual、override、abstract、sealed、new、extern三大类修饰符库组合使用public virtual、publ

9、ic new、public staticVehicle类增加成员修饰class Vehicle public int color; public readonly byte wheels; protected float weight; internal float speed; public const int seats= 4; public static int nums; public void Run() public void Stop()Vehicle v1= new Vehicle();v1.speed = 100;v1.color = 0;v1.Run();v1.Stop()

10、;byte b=v1.wheels;v1.wheels=4;/错误,只读int s1=v1.seats;/错误,只能通过类名称访问int s1= Vehicle.seats;/正确类的构造函数与析构函数类的构造函数与析构函数是类的两个特殊方法成员(无返回值)。构造函数用于初始化类的成员,而析构函数则用于释放类占用的资源。构造函数的函数名称与类名称相同。析构函数的函数名称是在类名称前面加上“”, 实例构造函数用于初始化类的非静态字段,是在用new关键词创建类的实例时自动被调用的静态构造函数用于初始化类的静态字段,是在第一次引用类的静态字段或第一次由类定义对象时被调用的 析构函数是在类的对象实例被

11、销毁时被自动调用的构造函数定义实例构造函数定义 修饰符 类名称(参数表) 函数体; 一般用public修饰一个类可以有多个实例构造函数(重载)不同的构造函数以参数的类型或数量加以区分以该类的对象作为构造函数的参数利用已有对象创建新对象 静态构造函数定义 修饰符修饰符 类名称类名称() 函数体函数体; 一般用一般用static修饰修饰一个类只能有1个静态构造函数构造函数示例class Vehicle . static Vehicle() nums =0; public Vehicle() wheels = 1;speed = 10; nums +; public Vehicle(byte wh,

12、 float s) wheels = wh; speed = s; nums +; public Vehicel(Vehicel v1) wheels=v1.wheets; speed=v1.speed; nums +; int n1=Vehicle.nums;/n1=0; /调用静态构造函数Vehicle v1= new Vehicle();/调用无参数的构造函数int w1=v1.wheels;/w1=1n1=Vehicle.nums;/n1=1Vehicle v2 = new Vehicle(4,60);/调用两个参数的构造函数int w2=v2.wheels;/w2=4n1=Vehic

13、le.nums;/n1=2Vehicel v3=new Vehicel(v2);/调用对象参数的构造函数int w3=v3.wheels;/w3=4n1=Vehicle.nums;/n1=3析构函数定义析构函数定义类名称() 函数体; 一个类只能有1个析构函数。如果没有定义析构函数,C#自动提供一个默认析构函数Vehicle() Console.WriteLine(销毁Vehicle对象); /每个创建的Vehicle对象被销毁时都会调用该函数this关键词代表当前对象实例本身。如果是在构造函数中使用this,表示对正在构造对象的引用;如果是在方法中使用this,表示对正在调用该方法的对象的引

14、用在构造函数或方法中,如果构造函数或方法的形参名称与类的成员字段名称一致,就必须用this加以区别 public Vehicle(byte wheels, float speed) this.wheels =wheels ; this.speed =speed ;/参数wheels与Vehicle类的字段wheels同名C#类的方法成员类的方法成员是指在类内部定义的函数,用于操作类的数据成员,方法包括实例方法和静态方法两种,前者通过对象实例操作,而后者通过类操作方法成员的申明修饰符 返回结果类型 方法名称(参数表) 方法体;返回结果类型表示执行该方法后所得到结果的数据类型。如果方法没有返回结果

15、,返回结果用void表示Main方法就是类Program的静态方法,该方法没有返回结果(类型为void),带有一个字符串数组类型的参数args ,表示系统提供给应用程序的命令行参数 static void Main(string args) return 语句return语句用在方法中以返回方法的结果,程序运行到任意一个return语句处都会结束方法如果方法有返回结果,return后面跟一个表达式,其结果类型要求与方法的返回结果类型一致;如果方法没有返回结果,则return后面不跟任何表达式 方法的修饰符前面介绍的类成员修饰符static修饰的方法为静态方法,无static修饰的为实例方法。静

16、态方法只能访问类的静态字段,而实例方法既可以访问类的非静态字段,也可以访问类的静态字段。静态方法只能用类名称访问,而不能用由类创建的对象访问用virtual修饰的方法为虚方法,虚方法可以在派生类进行重载,以实现基类与派生类中同名方法的不同功能方法成员实例方法声明:public bool IsVehicle() return speed0?true :false ; 方法调用:Vehicle v2 = new Vehicle(4,0);bool b1 = v2.IsVehicle(); 方法的参数方法的参数用于在调用时将数据传入方法或把方法的数据传出来。声明方法时指定的参数表称为形式参数(形参)

17、,调用方法时给出的具体参数称为实际参数(实参),实参与形参的数量、类型与顺序必须保持一致。当某个方法有多个参数时,参数之间用逗号隔开参数的传递方式值参数:没有任何修饰,传递参数的值引用参数:用ref修饰,传递参数的地址输出参数:用out修饰,参数修改内容可以返回数组类型参数:用params修饰,表示多个参数值参数值参数在申明时不加任何修饰。这样的参数传递到方法中时,只是将实参的备份数据传递过去,在方法中对值参数所作的修改不会影响原来的实参 具体调用时,系统为值参数临时分配一个存储单元,然后将实参值复制到这个临时单元中,方法中访问的是临时存储单元中的数据,而不是实参本身 值参数只能传入,不能传出

18、 private void swap(int x,int y) int c; c=x;x=y;y=c;static void Main(string args) int a = 10, b = 20; Program p1 = new Program(); p1.swap(a, b); /a和b没有发生变化值参数值参数在申明时不加任何修饰。这样的参数传递到方法中时,只是将实参的备份数据传递过去,在方法中对值参数所作的修改不会影响原来的实参 具体调用时,系统为值参数临时分配一个存储单元,然后将实参值复制到这个临时单元中,方法中访问的是临时存储单元中的数据,而不是实参本身 值参数只能传入,不能传出

19、 值参数的类型可以是值类型,也可以是引用类型 private void swap(int x,int y) int c; c=x;x=y;y=c;static void Main(string args) int a = 10, b = 20; Program p1 = new Program(); p1.swap(a, b); /a和b没有发生变化引用类型的值参数对于引用类型的值参数,也是将引用变量的备份传递给方法,由于引用变量中存放是数据在堆中的存储单元地址,引用变量的备份中存放的也是实参数据的存储地址,通过引用变量备份操作的数据就是实参的数据,对其修改会影响实参。如果在方法中仅仅是操作引

20、用变量而不是操作引用变量对应的数据,则不会影响实参 private void swap1(int x, int y) int z; z = x; x = y; y = z;private void reserve(int x) int c; for (int i = 0; i x.Length / 2; i+) c = xi; xi = xx.Length - 1 - i; xx.Length -1-i=c; 引用参数引用参数以ref修饰。这样的参数传递到方法中时,是将实参的地址传递过去,在方法中对引用参数所作的操作实际上就是操作实参,操作结果会影响原来的实参 引用参数既能够传入,也能够传出

21、由于引用参数需要将实参的地址传递给形参,要求实参必须是变量而不能是常数,而且引用参数在调用前必须已经被初始化 private void swap(ref int x,ref int y) int c; c=x;x=y;y=c;static void Main(string args) int a = 10, b = 20; Program p1 = new Program(); p1.swap(ref a, ref b); /a和b发生变化输出参数输出参数以out修饰。输出参数与引用参数类似,将其传递到方法中时,也是将实参的地址传递过去,在方法中对输出参数所作的操作实际上就是操作实参,操作结果

22、会影响原来的实参与引用参数不同的是,输出参数在调用前不需要初始化,在方法中不能接受传入的实参数据,而在方法结束前中必须给输出参数赋值 private int CalcMaxMinAvg(int x,out int Max,out int Min) int max, min,avg; max=min=avg= x0; for (int i=1;imax) max=xi; if(ximin) min=xi; avg+=xi; avg/=x.Length ;Max=max;Min=min; return avg;int x = 9,4,10,34,6,1,8;int Max1, Min1, Avg1

23、;Program p1 = new Program();avg1 = p1.CalcMaxMinAvg(x, out Max1, out Min1);数组参数数组参数以params修饰。采用数组参数,可以为方法提供可变长度的参数,即可以给方法传递任意个参数 private int CalcSum(params int x) int sum = 0; if (x.Length = 0) return 0; for (int i = 0; i x.Length; i+) sum += xi; return sum;int a = 9,4,10,34,6,1,8;int Sum1,Sum2;Prog

24、ram p1 = new Program();Sum1 = p1.CalcSum(1,2,3,4,5) ;/5个参数Sum2 = p1.CalcSum(a); /1个参数数组参数与数组类型参数比较给数组参数赋值时,实参可以是一个数组,也可以是多个数据的列表,如上例中,分别以数据列表“1,2,3,4,5”作为实参或者以数组a 作为实参;而数组类型参数赋值时,实参只能是一个数组。方法中对数组类型参数的数组元素修改会影响实参,即修改的数据能够传回来;而对数组参数的数组元素修改不会影响实参,传递给方法的实际是实参数据的备份。数组类型参数可以用一维数组,也可以用多维数组;数组参数只能用一维数组 静态方法

25、类的静态方法只能访问类的静态字段,用static修饰。静态方法属于类,而实例方法则是属于由类创建的对象实例。静态方法通过类名称调用,而实例方法通过对象名称调用 static int CalcSum(params int x) int sum = 0; if (x.Length = 0) return 0; for (int i = 0; i x.Length; i+) sum += xi; return sum;int x = 9,4,10,34,6,1,8;int Sum1,Sum2;Sum1 = Program.CalcSum(1,2,3,4,5) ;Sum2 =Program.CalcS

26、um(x); 外部静态方法static修饰符可以与extern修饰符配合使用,表示这是个外部静态方法,主要用于说明由其它DLL(动态链接库)提供的方法,包括由Windows系统提供的API(应用程序编程接口)函数的说明,无函数体一旦说明,就可以在某个类中直接使用 DllImport(User32.dll)private static extern int MessageBox(int handle, string message,string caption,int type);MessageBox(0, 欢迎使用C#进行程序设计 !, 提示, 0); 方法重载C#提供了方法重载机制,可以实现

27、方法名称相同而参数不同的多个方法 由方法的名称、参数的个数、参数的类型共同组成方法的签名,只要这三者有一项不同,就认为是不同的方法 方法的返回结果不是方法签名的一部分,C#不允许出现名称与参数都一致而返回结果类型不同的多个方法 private void swap(ref int x, ref int y) int c; c = x; x = y; y = c;private void swap(ref float x, ref float y) float c; c = x; x = y; y = c;泛型方法泛型提供了一种新的方法参数类型:类型参数。在声明方法时,不需要指定具体的参数类型,而

28、是在调用时将参数类型一起提供给方法修饰符 返回结果类型 方法名称(T参数,) 方法体; private void swap(ref T x, ref T y) T c; c = x; x = y; y = c;int a = 10, b = 20;Program p1 = new Program();p1.swap(ref a, ref b); float f1 = 10f, f2 = 20f;p1.swap(ref f1, ref f2); 方法的递归调用C#允许方法递归调用。递归调用就是方法调用自己编写递归调用的方法时,一定要有保证递归结束的语句,否则会无限递归下去,直到栈溢出 stati

29、c int Fact(int n) if (n = 1) return 1;/递归结束 else return n * Fact(n - 1);C#类的运算符重载成员C#提供了运算符重载机制,可以对类使用运算符C#允许重载的运算符包括:一元运算符:+、-、!、+、-、true、false二元运算符:+、-、*、/、%、&、|、=、!=、=、和=和(运算符)C#相关语句=运算符的左边列出了匿名方法需要的参数,参数有三种不同写法:(类型1 形参1,类型2 形参2):用括号起来的多个形参,每个形参指定其类型。参数之间用逗号隔开。(形参1,形参2):只需要形参,不必指定其类型。匿名委托时,根据声明的委

30、托类型,C#能够判断每个参数的类型。形参1:只有一个形参时,不需要括号 Delegate1 d1 = (x1, y1) = return x1 + y1; ;Delegate1 d2 =(x1,y1)= x1-y1;double x = 10, y = 20;Console.WriteLine(0+1=2, x, y, d1(x, y);Console.WriteLine(0-1=2, x, y, d2(x, y);C#类的事件成员事件是当类在发生某种需要被关注的事情时提供通知的一种方式发送事件的一方称为事件发送器,接收事件的一方称为事件接收器 。事件接收器需要提供一个事件处理程序处理接收的事

31、件某个对象接收到事件后会自动调用相应的程序,这样的程序称为事件处理方法(或称为回调函数)。C#利用委托机制实现事件处理方法 C#处理事件的步骤:声明一个事件委托类型在类中创建事件处理方法。事件处理方法与类的普通方法没有区别,一般以public修饰声明一个事件订阅与取消订阅事件,给事件指定处理方法 事件委托类型声明事件委托类型是一种特殊的委托类型,其返回类型为void类型,参数包括触发事件的对象名称和事件参数修饰符delegate void 事件委托类型名称(触发事件对象名称,事件参数);.NET框架提供了事件参数的基类EventArgs,声明事件委托类型时,可以直接使用EventArgs类,也

32、可以使用该类的派生类 事件委托类型的修饰符与普通委托类型的修饰符相同。采用public或internal修饰。一般省略,默认为internal 由于在事件发送器和事件接收器中都需要用到事件委托类型,一般在命名空间中声明事件委托类型 public delegate void EventHandler(object sender, EventArgs e);事件声明事件是类的成员,以关键词event声明,其格式如下修饰符 event 事件委托类型名称 事件名称; 事件声明一般放在触发事件的类中,其修饰符一般为public 在需要触发的代码处,以事件名称()这样的形式触发事件/声明事件成员publi

33、c event EventHandler Event1;/触发事件Event1();订阅与取消订阅事件订阅事件就是将事件与事件处理方法关联,采用的是委托的多重委托机制,订阅采用+=运算符 事件类对象名称.事件名称+=new 事件委托类型名称(事件处理方法); 取消订阅则是取消事件与事件处理方法的关联,取消订阅采用-=运算符 事件类对象名称.事件名称-=new 事件委托类型名称(事件处理方法); obj.Event1+=new EventHandler(TextChange) ;obj.Event1 -= new EventHandler(TextChange); C#事件成员示例-1class

34、 MyEventArgs : EventArgs/派生新的事件参数类 public string text; delegate void EventHandler(object sender, MyEventArgs e);/声明事件委托类型 class SenderEvent public event EventHandler Event1;/声明事件成员Event1 public string Text/自动实现属性Text get; set; public void SetText(string text) Text=text; MyEventArgs e1=new MyEventArg

35、s ();/事件参数类实例化 e1.text = Text; Event1(this, e1);/触发事件Events C#事件成员示例-2class Program static void Main(string args) SenderEvent obj=new SenderEvent() ;/ SenderEvent类实例化 obj.Event1+=new EventHandler(TextChange) ;/订阅事件(静态方法) obj.SetText(北京科技大学); /调用SetText方法,触发Event1事件 obj.Event1 -= new EventHandler(Tex

36、tChange); /取消订阅事件 Program p1 = new Program(); obj.Event1 += new EventHandler(p1.TextChange1); /订阅事件(实例方法) obj.SetText(“C#程序设计”);/调用SetText方法,触发Event1事件 public static void TextChange(object ob,MyEventArgs e)/静态方法 Console.WriteLine(触发对象为:0,文字是:1,ob, e.text); public void TextChange1(object ob,MyEventAr

37、gs e)/实例方法 Console.WriteLine(触发对象为:0,文字是:1,ob, e.text); C#类的继承继承是面向对象程序设计的重要特性之一,通过继承,派生类可能拥有基类的所有成员,派生类可以在基类的基础上增加新的成员,派生类也可以重写覆盖被继承的基类成员方法 一个类从另外一个类派生而来,称之为派生类或子类,被派生的类称为基类或父类。派生类也可以作为其他类的基类C#中所有声明的类都是其它类的派生类,即使在声明时没有指定基类,也是隐含派生自object类 类继承的特点C#的类继承只允许单一继承,即一个派生类只能有一个基类。但是C#的派生类还允许继承多个接口。也就是说,一个类可

38、以由一个基类和多个接口派生而来。通过接口实现了类似于C+的多重继承功能C#派生类只能继承基类的公共成员和保护成员,不能继承其私有成员C#不能继承基类的构造函数和析构函数C#的继承是可以传递的。派生类继承了其直接基类的成员,也继承了其间接基类的成员可以给派生类增加新成员,但不能删除继承而来的基类成员。C#允许重写继承而来的基类成员方法。C#派生类定义的对象也是基类对象,但基类定义的对象不一定是派生类对象 类的派生派生类定义时用冒号指定基类和接口 类修饰符 class 派生类: 基类,接口列表 派生类体; 基类可以是C#或.NET框架提供的基类,也可以是程序中已经定义过的其它类 派生类创建的对象实

39、例可以赋给基类对象,反之,基类对象实例不能赋给派生类对象 派生类示例-1 struct POINT/声明结构POINT public double x, y; class Shape/声明基类Shape protected POINT p1;/保护字段成员 private bool IsShape() return false; /私有方法成员 public Shape()/无参数构造函数 p1.x=p1.y=0; public Shape(POINT p)/带1个参数构造函数 p1=p; public double Area()/公共方法成员 return 0; 派生类示例-2 class

40、Rectangle : Shape /由基类Shape派生新类Rectangle private POINT p2; public Rectangle(POINT p1, POINT p2)/新类构造函数 this.p1 = p1; this.p2 = p2; public double Area1() /新类计算面积的方法Area1,与基类Area名称不同 return (p2.x-p1.x )*(p2.y-p1.y); 派生类示例-3POINT p1, p2;p1.x=p1.y=1;p2.x=p2.y=2;Shape s1 = new Shape(p1);/由基类创建对象s1Rectang

41、le r1 = new Rectangle(p1, p2);/由派生类Rectangle创建对象r1s1=r1;/合法,派生类对象实例赋值给基类对象变量r1=s1; /不合法派生类的构造函数与析构函数派生类构造函数的调用顺序是:先根据类的层次结构,找到最顶层的基类,调用其构造函数,再按层次顺序,调用有关类的构造函数,最后调用派生类的构造函数。这样的调用顺序能够保证把派生类的所有资源都准备好先调用Shape类构造函数,再调用Rectangle类构造函数析构函数的调用顺序与构造函数相反:先调用派生类的析构函数,然后从底到顶按顺序调用相应类的析构函数 在调用派生类的构造函数时,默认调用基类无参数构造

42、函数,也可以指定调用基类的哪个构造函数。这时采用base关键词表示基类 修饰符 派生类名称(构造函数参数表):base(基类构造函数参数表) 派生类指定调用的基类构造函数示例 class Rectangle : Shape private POINT p2; public Rectangle(POINT p1, POINT p2):base(p1) /指定调用基类的带1个参数的构造函数 this.p2 = p2; /基类Shape构造函数已经初始化了p1点 /派生类仅仅需要初始化p2点 public double Area1() return (p2.x-p1.x )*(p2.y-p1.y);

43、 类的多态多态是面向对象程序设计的重要特性之一。所谓多态性(polymorphism),是指同一事物在不同的条件下具有不同的表现行为,在面向对象程序设计时,执行某一操作时,根据条件不同,可能会执行不同的具体操作。方法成员重载就是一种多态 有时在类的继承关系中,派生类与基类可能也会遇到同样名称的方法问题,涉及到派生类的方法重写或覆盖问题 如果派生类的方法虽然与基类方法名称相同,但参数的类型、数目、顺序其中之一不同时,C#认为这是不同的方法签名,也就是不同的方法,这种情况与同一个类中方法的重载相似,无需方法重写或覆盖 利用new修饰符隐藏基类同名方法当派生类需要声明与基类相同签名的方法时,在方法前

44、加上new修饰符,则在派生类中隐藏了基类的相同签名方法。通过派生类所调用的方法是派生类自己的,而非基类的相同签名方法 class Rectangle : Shape private POINT p2; public Rectangle(POINT p1, POINT p2):base(p1) this.p2 = p2; public new double Area()/new关键词,隐藏了基类的Area方法 return (p2.x-p1.x )*(p2.y-p1.y); Rectangle r1 = new Rectangle(p1, p2);double a1=r1.Area(); /调用

45、的是Rectangle 类的Area方法利用利用virtual和和override修饰符实现虚方法重写修饰符实现虚方法重写 在基类声明一个方法时,在方法前面加上virtual修饰符,该方法就成为虚方法。不能将类的静态方法声明为虚方法 当以具有虚方法的类作为基类派生子类时,在虚方法前面加上override修饰符就可以实现虚方法的重写 虚方法的声明格式如下:/基类访问修饰符 virtual 虚方法名称(参数) 方法体;虚方法的重写格式如下:/派生类访问修饰符 override 虚方法名称(参数) 方法体;重写虚方法注意事项重写虚方法注意事项只能重写虚方法,重写的方法签名必须与基类的虚方法签名相同。

46、可重写的基类方法必须是用virtual、abstract和override三种修饰符之一修饰的方法。不能重写静态方法。重写不能改变虚方法的访问权限,即,重写的访问修饰符应该与虚方法的访问修饰符相同。override不能与new、static、virtual和abstract修饰符一起使用。属性和索引器也可以利用virtual与override重写 无论是用new新声明方法,还是重写虚方法,这样的派生类作为其他类的基类时,仍然可以用new新声明方法或者用override重写虚方法 重写虚方法示例重写虚方法示例class Shape protected POINT p1; public Shape

47、(POINT p) p1=p; public virtual double Area() /基类声明虚方法 return 0; class Rectangle1 : Shape private POINT p2; public Rectangle1(POINT p1, POINT p2):base(p1) this.p2 = p2; public override double Area() /派生类重写虚方法 return (p2.x-p1.x )*(p2.y-p1.y) ; 虚方法重写与虚方法重写与new修饰符隐藏的区别修饰符隐藏的区别 采用new修饰符隐藏,派生类中其实存在两个方法,一个

48、是继承自基类的方法,另外一个是用new修饰符新声明的方法,继承的方法处于隐藏状态;采用虚方法重写,派生类中只有一个方法,派生类没有继承基类的方法,只有重写的那个方法。当用基类对象表示派生类对象实例时,new修饰符隐藏方式调用的是基类的方法,而虚方法重写方式调用的是派生类的方法New隐藏方式:Shape s1 = new Shape(p1);Rectangle r1 = new Rectangle(p1, p2);s1=r1;s1.Area(); /调用shpae类的Area虚方法重写方式:Shape s1 = new Shape(p1);Rectangle1 r1 = new Rectangl

49、e1(p1, p2);s1=r1;s1.Area(); /调用Rectangle1 类的Areabase关键词关键词 base关键词可以在定义派生类的构造函数时指示调用基类的哪个构造函数base关键词还可以在派生类中用于调用基类的方法 public override double Area() return base.Area() * height; /调用基类的Area方法public new double Area() return base.Area() * height; /调用基类的Area方法抽象类与抽象方法抽象类与抽象方法 前述基类Shape并不能够代表任何形状,是个抽象的概念,

50、其中计算面积的的Area方法没有实际性的意义。这样的类可以声明为抽象类一旦将某个类声明为抽象类,就不能利用该类创建对象实例,只能作为其他类的基类抽象类的声明用abstract修饰,其声明格式如下:类访问修饰符 abstract class 抽象类名称 类体; 抽象类中,可以利用abstract修饰符将某个方法声明为抽象方法,由派生类用override修饰符重写抽象方法。抽象方法声明时没有具体实现,也就是没有方法体,不需要大括号。访问修饰符 abstract 抽象方法名称(参数表); 抽象类与抽象方法抽象类与抽象方法 的特点抽象类不能实例化。抽象类可以定义自己的构造函数,但这些构造方法是在实例化

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

当前位置:首页 > 办公、行业 > 各类PPT课件(模板)
版权提示 | 免责声明

1,本文(C#程序设计-第三章ppt课件.ppt)为本站会员(三亚风情)主动上传,163文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。
2,用户下载本文档,所消耗的文币(积分)将全额增加到上传者的账号。
3, 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(发送邮件至3464097650@qq.com或直接QQ联系客服),我们立即给予删除!


侵权处理QQ:3464097650--上传资料QQ:3464097650

【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。


163文库-Www.163Wenku.Com |网站地图|