《第四章 面向对象编程进阶.ppt》由会员分享,可在线阅读,更多相关《第四章 面向对象编程进阶.ppt(67页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第第第四章四章四章四章 面向对象编程进阶面向对象编程进阶面向对象编程进阶面向对象编程进阶本章学习目标本章学习目标理解类的继承与多态的概念理解类的继承与多态的概念熟悉类型转换的方法熟悉类型转换的方法掌握结构与接口的定义及用法掌握结构与接口的定义及用法掌握异常处理的方法掌握异常处理的方法掌握委托的定义及用法掌握委托的定义及用法第第四章四章 面向对象编程进阶面向对象编程进阶4.1 类的继承与多态类的继承与多态4.3 类型转换类型转换4.4 结构与接口结构与接口4.6 异常处理异常处理4.7 委托委托4.1 类的继承与多态类的继承与多态4.1.1 继承继承4.1.2 多态多态4.1.1 继承继承类的
2、继承性:类的继承性:C#允许基于某一个已经定义的类来创建一个允许基于某一个已经定义的类来创建一个新类。新类。基类:被继承的类,即父类。基类:被继承的类,即父类。派生类:继承的类,即子类。派生类:继承的类,即子类。4.1.1 继承继承访问修饰符访问修饰符 class 类名类名:基类基类 类主体类主体 访问修饰符:访问修饰符:public:表示不限制对类的访问;:表示不限制对类的访问;internal:可被同一个项目的程序访问;可被同一个项目的程序访问;sealed:表示一个密封类,不能被继承。表示一个密封类,不能被继承。说明:说明:如果对类不指定访问修饰符,则类的默认访问修饰符为如果对类不指定访
3、问修饰符,则类的默认访问修饰符为internal 定义派生类定义派生类4.1.1 继承继承 class Person public string name;protect string sex;int age;class Student:Person string stuNo;string classNo;定义派生类定义派生类4.1.1 继承继承派生类只能继承于一个基类;派生类只能继承于一个基类;派生类自然继承基类的成员,但不能继承基类的构造函数成员;派生类自然继承基类的成员,但不能继承基类的构造函数成员;类的继承可以传递。如类的继承可以传递。如C类继承类继承B类,类,B类继承类继承A类,则类
4、,则C类即具类即具有有B类和类和A类的成员;类的成员;派生类是对基类的扩展,派生类定义中可以声明新的成员,但不派生类是对基类的扩展,派生类定义中可以声明新的成员,但不能消除已继承的基类成员;能消除已继承的基类成员;派生类定义中如果声明了与基类同名的成员,则基类的同名成员派生类定义中如果声明了与基类同名的成员,则基类的同名成员将被隐藏,从而使派生类不能直接访问同名的基类的成员;将被隐藏,从而使派生类不能直接访问同名的基类的成员;基类可以定义虚方法成员等,这样派生类能够重载这些成员以表基类可以定义虚方法成员等,这样派生类能够重载这些成员以表现类的多态性。现类的多态性。类的继承规则类的继承规则4.1
5、.1 继承继承派生类构造函数派生类构造函数默认执行基类的无参构造函数,如果要执行基类有参构默认执行基类的无参构造函数,如果要执行基类有参构造函数,则必须在派生类构造函数的基表列表中指出;造函数,则必须在派生类构造函数的基表列表中指出;如果基类具有带参数的构造函数,则派生类必需具有向如果基类具有带参数的构造函数,则派生类必需具有向基类传递参数的带参构造函数;基类传递参数的带参构造函数;构造函数调用顺序:构造函数调用顺序:先基类后派生类先基类后派生类。派生类析构函数派生类析构函数析构函数调用顺序:析构函数调用顺序:先派生类后基类先派生类后基类。4.1.1 继承继承base在派生类中调用基类方法在派
6、生类中调用基类方法在构造函数中显式调用基类构造函数在构造函数中显式调用基类构造函数public 派生类名派生类名(形参列表形参列表):base(基类构造函数实参列表基类构造函数实参列表)在方法中调用基类方法在方法中调用基类方法 base.基类方法名基类方法名(参数表参数表)4.1.1 继承继承隐藏隐藏隐藏隐藏自动隐藏与基类同名的成员自动隐藏与基类同名的成员声明成员时,显式使用声明成员时,显式使用new修饰符修饰符隐藏实质上是使继承的成员在派生类成为不可见的。隐藏隐藏实质上是使继承的成员在派生类成为不可见的。隐藏的成员并没有被删除,只是不能从派生类直接访问,通过基类的成员并没有被删除,只是不能从
7、派生类直接访问,通过基类能够直接访问它。能够直接访问它。4.1.2 多态多态编译时实现的多态:编译时实现的多态:如果一个类中有两个或两个以上的方法的名字相同,而它们如果一个类中有两个或两个以上的方法的名字相同,而它们的形参个数或形参类型有所不同,在程序编译时能够正确区的形参个数或形参类型有所不同,在程序编译时能够正确区别他们;别他们;运行时实现的多态:运行时实现的多态:指在指在程序运行时程序运行时,基类对象执行一个基类与派生类都具有的,基类对象执行一个基类与派生类都具有的同名方法调用同名方法调用时,程序可以时,程序可以根据基类对象类型的不同根据基类对象类型的不同(基类(基类还是派生类)进行正确
8、的调用。还是派生类)进行正确的调用。实现方法:实现方法:虚方法、抽象方法虚方法、抽象方法 4.1.2 多态多态虚方法虚方法public virtual 返回类型返回类型 方法名(参数列表)方法名(参数列表)方法体方法体 基类中定义虚方法基类中定义虚方法public override 返回类型返回类型 方法名(参数列表)方法名(参数列表)方法体方法体 派生类中重写基类中定义虚方法派生类中重写基类中定义虚方法4.1.2 多态多态虚方法虚方法几点说明:几点说明:基类与派生类中的方法名、参数列表、返回类型必基类与派生类中的方法名、参数列表、返回类型必须完全一致;须完全一致;可被重写的基类方法是可被重写
9、的基类方法是虚方法、抽象方法或重写方虚方法、抽象方法或重写方法(法(override修饰)修饰)virtual不能与不能与static、abstract或或override中任一个同中任一个同时出现;时出现;override不能与不能与new、static、virtual或或abstract中任中任一个同时使用;一个同时使用;4.1.2 隐藏与多态实例隐藏与多态实例隐藏与多态隐藏与多态class A public void E()Console.WriteLine(“A.E”);public void F()Console.WriteLine(“A.F”);public virtual voi
10、d G()Console.WriteLine(“A.G”);class B:A public void E()Console.WriteLine(“B.E”);public new void F()Console.WriteLine(“B.F”);public override void G()Console.WriteLine(“B.G”);class Test public static void Main()B b=new B();A a=b;a.E();b.E();a.F();b.F();a.G();b.G();输出结果:输出结果:A.EB.EA.FB.FB.GB.G父类可以引用子类对
11、象,父类可以引用子类对象,父类引用只能调用子类继承自父类的方法父类引用只能调用子类继承自父类的方法,父类不能调用子类独有的方法。父类不能调用子类独有的方法。4.1.2 隐藏与多态实例隐藏与多态实例隐藏与多态隐藏与多态class A public virtual void F()Console.WriteLine(“A.F”);class B:A public override void F()Console.WriteLine(“B.F”);class C:B new public virtual void F()Console.WriteLine(“C.F”);class D:C publi
12、c override void F()Console.WriteLine(“D.F”);class Test public static void Main()D d=new D();A a=d;B b=d;C c=d;a.F();b.F();c.F();d.F();输出结果:输出结果:B.FB.FD.FD.F4.1.2 多态多态抽象类与抽象方法抽象类与抽象方法抽象类:是一种特殊的基类,该类并不与具体的事物发生抽象类:是一种特殊的基类,该类并不与具体的事物发生联系;例如几何体,计算几何体体积的方法不可能有具体联系;例如几何体,计算几何体体积的方法不可能有具体实现过程,只有具体某一种几何体才有求
13、体积的方法;实现过程,只有具体某一种几何体才有求体积的方法;抽象类是指在基类的定义中声明不包含任何实现代码的方抽象类是指在基类的定义中声明不包含任何实现代码的方法,实际上就是一个不具有任何具体功能的方法,即法,实际上就是一个不具有任何具体功能的方法,即抽象抽象方法方法。该方法的唯一作用就是让派生类来重写;。该方法的唯一作用就是让派生类来重写;在基类定义中,只要类体中包含一个抽象方法,该类即为在基类定义中,只要类体中包含一个抽象方法,该类即为抽象类。抽象类。4.1.2 多态多态抽象类与抽象方法抽象类与抽象方法public abstract class 类名类名 public abstract 返
14、回类型返回类型 方法名称(参数列表);方法名称(参数列表);声明抽象类与抽象方法声明抽象类与抽象方法不包含方法体,不包含方法体,也不能要也不能要4.1.2 多态多态抽象类与抽象方法抽象类与抽象方法抽象类几点说明抽象类几点说明一个类中只要包含一个抽象方法,该类即为抽象类;反之,一个类中只要包含一个抽象方法,该类即为抽象类;反之,一个抽象类中必须包含抽象方法;一个抽象类中必须包含抽象方法;抽象类中可以包含非抽象方法;抽象类中可以包含非抽象方法;抽象类不能实例化,抽象类不能实例化,不能用不能用new生成实例;生成实例;抽象类抽象类不能被密封不能被密封。派生类说明派生类说明如果基类为抽象类,则要求派生
15、类如果基类为抽象类,则要求派生类必须重载必须重载实现基类中实现基类中所有所有抽象方法抽象方法。抽象方法说明抽象方法说明抽象方法抽象方法没有方法体没有方法体,只有一个方法头后跟一个分号;,只有一个方法头后跟一个分号;抽象方法被隐含认为是抽象方法被隐含认为是一种虚方法一种虚方法,派生类中必须重写所有派生类中必须重写所有抽象方法抽象方法,且重写的方法与抽象方法的参数及类型、方法名,且重写的方法与抽象方法的参数及类型、方法名都应相同。都应相同。4.1.2 多态多态抽象类与抽象方法抽象类与抽象方法public abstract class Shape protected double x;protect
16、ed double y;protected double z;public Shape(double dx,double dy,double dz)x=dx;y=dy;z=dz;public abstract double Cubage();定义抽象类及抽象方法定义抽象类及抽象方法4.1.2 多态多态抽象类与抽象方法抽象类与抽象方法public class Cuboid:Shape public Cuboid(double dx,double dy,double dz):base(dx,dy,dz)public override double Cubage()return x*y*z;重载抽象
17、方法重载抽象方法4.1.2 多态多态抽象类与抽象方法抽象类与抽象方法虚方法与抽象方法区别虚方法与抽象方法区别抽象方法必须抽象方法必须在抽象类中定义在抽象类中定义,虚方法可以在抽象类或一般,虚方法可以在抽象类或一般类中定义;类中定义;在基类中,虚方法用在基类中,虚方法用virtual关键字,抽象方法用关键字,抽象方法用abstract关关键字;键字;在派生类中,虚方法在派生类中,虚方法不一定重写不一定重写,抽象方法,抽象方法一定要重写一定要重写;修饰符小结修饰符小结基类方法基类方法abstractvirtualoverride无说明符无说明符new(无说明符无说明符)override派生类方法派
18、生类方法4.1.2 多态多态密封类和密封方法密封类和密封方法密封类:不允许被继承的类。密封类:不允许被继承的类。定义密封类定义密封类访问修饰符访问修饰符 sealed class 类名称类名称 类体类体 public sealed class SealedClass public string method()return 我是密封类我是密封类;定义密封类定义密封类4.1.2 多态多态密封类和密封方法密封类和密封方法基类中要密封的方法必须有基类中要密封的方法必须有virtual、abstract或或override派生类中的派生类中的密封方法必须同时有密封方法必须同时有sealed overr
19、ide。定义密封方法定义密封方法访问修饰符访问修饰符 sealed override 返回类型返回类型 方法名(参数列表)方法名(参数列表)方法体方法体 4.1.2 多态多态密封类和密封方法密封类和密封方法密封方法密封方法class A public virtual void F()Console.WriteLine(“A.F”);class B:A public sealed override void F()Console.WriteLine(“B.F”);class C:B public override void F()Console.WriteLine(“C.F”);class Te
20、st public static void Main()C c=new C();c.F();sealed必须与必须与override同时出现同时出现不允许重写不允许重写F方法方法若无若无override则为隐藏则为隐藏4.3 类型转换类型转换4.3.1 隐式类型转换隐式类型转换4.3.2 显式类型转换显式类型转换4.3.3 使用使用Convert转换转换为什么需要类型转换为什么需要类型转换编译器要编译器要确切地知道确切地知道数据的类型数据的类型int num=123;整数整数字符串字符串需要类型转换!需要类型转换!编译出错编译出错4.3.1 隐式类型转换隐式类型转换隐式转换:自动类型转换隐式转
21、换:自动类型转换floatfloatintint规则:对于数值类型,规则:对于数值类型,A的的取值范围取值范围完全包含在完全包含在B内内ABstatic void Main(string args)double score=58.5;/原始成绩原始成绩 int bonus=2;/加分加分 int sum;/总分总分 sum=score+bonus;/计算总分计算总分 Console.WriteLine(sum);Console.ReadLine();4.3.2 显式类型转换显式类型转换static void Main(string args)double score=58.5;int bonu
22、s=2;int sum;sum=(int)score+bonus;Console.WriteLine(sum);Console.ReadLine();明确明确告诉编译器转换类型告诉编译器转换类型注意:注意:double(58.5)-int(58),精度可能丢失!,精度可能丢失!显式转换:强制类型转换显式转换:强制类型转换使用使用 Parse()进行转换进行转换字符串和数值型字符串和数值型的互相转换的互相转换 intintfloatfloatdoubledoublestringstringint.Parse()float.Parse()double.Parse()ToString()必须是数字的
23、必须是数字的有效表示形式!有效表示形式!4.3.3 使用使用 Convert 类进行转换类进行转换使用使用 Convert:Convert.ToXxx(object value)Convert.ToInt32()Convert.ToSingle()Convert.ToString()double85.63string85.63int86float85.63Parse 与与 ConvertXxx.Parse(string)目标类型的有效表示形式目标类型的有效表示形式Convert.ToXxx(object):注:注:Xxx表示某种类型表示某种类型字符串字符串其他类型其他类型任意类型任意类型其他类
24、型其他类型4.4 结构与接口结构与接口访问修饰符访问修饰符struct 结构名结构名 结构主体结构主体 访问修饰符:访问修饰符:public:表示不限制对结构的访问;:表示不限制对结构的访问;internal:可被同一个项目的程序访问(可被同一个项目的程序访问(默认默认););结构成员包括字段、属性、方法等;结构成员包括字段、属性、方法等;结构可以定义构造函数,但不能定义析构函数;结构可以定义构造函数,但不能定义析构函数;定义构造函数时不能采用缺省方式(无参数)。定义构造函数时不能采用缺省方式(无参数)。结构的声明结构的声明4.4 结构与接口结构与接口结构与类的区别结构与类的区别结结 构构类类
25、值类型引用类型可以不使用new实例化必须使用new初始化不可以添加无参构造函数可以添加无参构造函数没有析构函数有析构函数没有abstract,protected和sealed修饰符可以使用abstract,protected和sealed修饰符不支持继承支持继承适用于表示小的数据结构适用于表示任何数据结构4.4 结构与接口结构与接口struct account public string name;public double balance;public account(string n,double b)name=n;balance=b;结构定义及使用(一)结构定义及使用(一)4.4 结构与
26、接口结构与接口结构定义及使用结构定义及使用(一)续一)续class Test public static void Main()account acc1=new account(“张三张三”,3000);/显式构造函数显式构造函数 account acc2=new account();/缺省构造函数缺省构造函数account acc3;/没有构造函数没有构造函数Console.WriteLine(acc1.name+“has a balance of”+acc1.balance);if(acc2.name=null)Console.WriteLine(“acc2.name is null”);
27、Console.WriteLine(“acc2.balance is”+acc2.balance);/使用使用acc3以前,必须初始化以前,必须初始化acc3 acc3.name=“Mary”;acc3.balance=2000;Console.WriteLine(acc3.name+“has a balance of”+acc3.balance);4.4 结构与接口结构与接口struct MyStruct public int x;public int y;public MyStruct(int i,int j)x=i;y=j;public void Sum()int sum=x+y;Con
28、sole.WriteLine(“The sum is 0”,sum);结构定义及使用(二)结构定义及使用(二)4.4 结构与接口结构与接口class Test static void Main()MyStruct s1=new MyStruct(1,2);MyStruct s2=s1;s1.x=2;s1.Sum();s2.Sum();结构定义及使用(二)续结构定义及使用(二)续输出结果:输出结果:The sum is 4The sum is 3值传递值传递4.4 结构与接口结构与接口接口声明定义了一个协定,使用接口的类或结构必须遵守接口声明定义了一个协定,使用接口的类或结构必须遵守其协定。接口
29、可以从多个基接口继承,而类或结构可以实其协定。接口可以从多个基接口继承,而类或结构可以实现多个接口;现多个接口;接口成员只能是方法、属性、索引和事件,接口成员只能是方法、属性、索引和事件,不能有字段不能有字段。接口本身不提供它所定义成员的实现代码,只指定实现该接口本身不提供它所定义成员的实现代码,只指定实现该接口的类或结构必须提供的成员的调用形式。接口的类或结构必须提供的成员的调用形式。4.4 结构与接口结构与接口访问修饰符访问修饰符 interface 接口名接口名:基接口:基接口1,基接口,基接口2.接口体接口体 访问修饰符:访问修饰符:public:表示不限制对类的访问;:表示不限制对类
30、的访问;internal:可被同一个项目的程序访问(可被同一个项目的程序访问(默认默认););接口成员包括属性、方法等;接口成员包括属性、方法等;接口不能包括字段,也不能定义构造函数和析构函数;接口不能包括字段,也不能定义构造函数和析构函数;接口成员访问修饰符接口成员访问修饰符默认为默认为public;接口的命名通常是以接口的命名通常是以I开头,如开头,如IPartA。接口的声明接口的声明4.4 结构与接口结构与接口接口的实现接口的实现函数成员的实现:类、结构;函数成员的实现:类、结构;实现接口类型:实现接口类型:public成员实现成员实现显示接口成员实现显示接口成员实现不能用不能用new操
31、作符创建接口的实例操作符创建接口的实例4.4 结构与接口结构与接口public成员实现成员实现实现接口成员时,声明成员为实现接口成员时,声明成员为public,这样的实现声明,这样的实现声明称为称为public接口成员实现声明,简称接口成员实现声明,简称public成员实现或成员实现或public实现实现;public实现的成员具有双重访问性,因为它是接口成员实现的成员具有双重访问性,因为它是接口成员的实现,所以可以通过接口实例来访问,又因为它是的实现,所以可以通过接口实例来访问,又因为它是public成员,还可以通过类或结构的实例来访问。成员,还可以通过类或结构的实例来访问。4.4 结构与接
32、口结构与接口interface IA void p();class B:IA public void p()/代码实现代码实现 class Test public static void Main()B b=new B();b.p();IA a=b;a.p();public成员实现成员实现(一一)(正确)(正确)(正确)(正确)4.4 结构与接口结构与接口public成员实现(二)成员实现(二)interface IPoint int Xget;set;int Yget;set;class MyPoint:IPoint private int myX,myY;public MyPoint(in
33、t x,int y)myX=x;myY=y;public int X /对属性对属性X的的public实现声明实现声明 getreturn myX;setmyX=value;public int Y /对属性对属性Y的的public实现声明实现声明 getreturn myY;setmyY=value;4.4 结构与接口结构与接口class MainClass /通过接口调用通过接口调用 public static void PrintPoint(IPoint p)Console.WriteLine(“x=0,y=1”,p.X,p.Y);public static void Main()MyP
34、oint p=new MyPoint(2,3);Console.Write(“MyPoint:”);PrintPoint(p);public成员实现(二)续成员实现(二)续输出结果:输出结果:MyPoint:x=2,y=34.4 结构与接口结构与接口显式接口成员实现显式接口成员实现用接口成员的完全限定名(用接口成员的完全限定名(接口名接口名.成员名成员名)来显式指)来显式指定要实现的接口成员,这样的实现声明称为显式接口定要实现的接口成员,这样的实现声明称为显式接口成员实现声明,简称显式实现声明成员实现声明,简称显式实现声明;注意:显式实现声明中不能用注意:显式实现声明中不能用public修饰符
35、。修饰符。4.4 结构与接口结构与接口interface IA void p();class B:IA void IA.p()/代码实现代码实现 class Test public static void Main()B b=new B();b.p();IA a=b;a.p();显式成员实现显式成员实现(一一)(错误)(错误)(正确)(正确)4.4 结构与接口结构与接口interface IA void p();interface IB void p();class C:IA,IB void IA.p()Console.WriteLine(“A.p”);void IB.p()Console.W
36、riteLine(“B.p”);public void p()Console.WriteLine(“C.p”);class Test public static void Main()C c=new C();c.p();(IA)c).p();(IB)c).p();显式成员实现显式成员实现(二二)输出结果:输出结果:C.pA.pB.p4.4 结构与接口结构与接口interface IA void p();class B:IA void IA.p()Console.WriteLine(“A.p”);public void p()Console.WriteLine(“B.p”);class C:B,
37、IA public static void Main()B b=new B();IA a=b;a.p();/显式接口成员实现优先显式接口成员实现优先 C c=new C();a=c;c.p();a.p();显式成员实现显式成员实现(三三)输出结果:输出结果:A.pB.pA.p类可以同时有一个基类和零个以上类可以同时有一个基类和零个以上的接口,并将的接口,并将基类写在前面基类写在前面4.6 异常处理异常处理异常异常指由于程序运行时发生的错误,从而导致程序错误结束。指由于程序运行时发生的错误,从而导致程序错误结束。异常处理异常处理 当程序运行过程中发生了某个异常现象,系统将产生一个当程序运行过程中
38、发生了某个异常现象,系统将产生一个相应的异常类对象,并把它交给系统处理,系统负责找到相应的异常类对象,并把它交给系统处理,系统负责找到处理错误的代码并执行,处理错误的代码并执行,如除数为如除数为0。4.6 异常处理异常处理使用语句或表达式在执行过程中自动引发了某个异常的条使用语句或表达式在执行过程中自动引发了某个异常的条件件,使得操作无法正常结束使得操作无法正常结束,从而引发异常;从而引发异常;使用显式使用显式 throw 语句来引发异常。在此情况下,控制权将语句来引发异常。在此情况下,控制权将无条件转到处理异常的部分代码。无条件转到处理异常的部分代码。引发异常两种方式引发异常两种方式C#中异
39、常处理语句中异常处理语句 trycatch trycatchfinally tryfinally throw4.6 异常处理异常处理try 被监控的可能发生异常的程序代码被监控的可能发生异常的程序代码catch(异常类名异常类名 异常变量名异常变量名)异常处理异常处理格式格式1 1try 被监控的可能发生异常的程序代码被监控的可能发生异常的程序代码finally 最终要执行的代码最终要执行的代码格式格式2 2try 被监控的可能发生异常的程序代码被监控的可能发生异常的程序代码catch(异常类名异常类名 异常变量名异常变量名)异常处理异常处理finally 最终要执行的代码最终要执行的代码格式
40、格式3 34.6 异常处理异常处理try子句包含可能引起异常的代码;子句包含可能引起异常的代码;只有发生异常时才执行只有发生异常时才执行catch子句,若没有异常,子句,若没有异常,try子句正子句正常结束,常结束,catch子句被忽略,程序转到子句被忽略,程序转到catch后的第一条语句后的第一条语句开始执行;开始执行;可以包含多个可以包含多个catch语句;语句;catch子句可以不包括参数,它将捕获所有类型的异常;子句可以不包括参数,它将捕获所有类型的异常;异常类名必须为异常类名必须为System.Exception或从或从System.Exception派生的类型;派生的类型;fina
41、lly子句不管有没有异常都执行。子句不管有没有异常都执行。4.6 异常处理异常处理异常类名称异常类名称说明说明ArithmeticException错误:由于数学运算导致的异常FormatException参数的格式不正确ArgumentNullException参数为空:给方法传递一个不可接受的空参数MemberAccessException访问错误:类型成员不能被访问数学计算ArrayTypeMismatchException数组类型不匹配DivideByZeroException被零除ArgumentException参数错误:方法的参数无效IndexOutOfRangeExceptio
42、n索引超出范围InvalidCastException非法强制转换,在显式转换失败时引发MulticastNotSupportedException不支持的组播:组合两个非空委派时引发NotSupportedException调用的方法在类中没有实现NullReferenceException引用空引用对象时引发OutOfMemoryException无法为新语句分配内存时引发,内存不足OverflowException溢出StackOverflowException栈溢出NotFiniteNumberException无限大的值:数字不合法4.6 异常处理异常处理int num1,num2,
43、result;try num1=int.Parse(Console.ReadLine();num2=int.Parse(Console.ReadLine();result=num1/num2;Console.WriteLine(“商是商是”+result);catch(DivideByZeroException error)Console.WriteLine(除数不能为零!除数不能为零!);catch(FormatException error)Console.WriteLine(输入格式错误!输入格式错误!);catch(Exception ex)/如果写,写在如果写,写在catch的最后的
44、最后 Console.WriteLine(“输入错误输入错误”);finally Console.WriteLine(谢谢使用!谢谢使用!);异常处理异常处理4.6 异常处理异常处理throw异常处理异常处理static int Divide(int x,int y)try int z=x/y;return z;catch(DivideByZeroException error)throw new DivideByZeroException(“除数不能为除数不能为0”);static void Main()int num1,num2,result;try num1=int.Parse(Cons
45、ole.ReadLine();num2=int.Parse(Console.ReadLine();result=Divide(num1,num2);Console.WriteLine(“商是商是”+result);catch(DivideByZeroException error)Console.WriteLine(error.Message);catch(FormatException error)Console.WriteLine(输入格式错误!输入格式错误!);catch(Exception ex)Console.WriteLine(“输入错误输入错误”);finally Console
46、.WriteLine(谢谢使用!谢谢使用!);4.7 委托委托委托也叫代理,就是把事情交给别人去办,如委托律师代理委托也叫代理,就是把事情交给别人去办,如委托律师代理打官司,委托同学代买火车票;打官司,委托同学代买火车票;C#中如果将一个方法委托给一个代理对象,那么这个对象就中如果将一个方法委托给一个代理对象,那么这个对象就可以全权代理这个方法的执行;可以全权代理这个方法的执行;使用委托首先要定义委托,声明委托能代理什么类型的方法,使用委托首先要定义委托,声明委托能代理什么类型的方法,就像房产中介能代理抵押贷款业务,而不能代理打官司;就像房产中介能代理抵押贷款业务,而不能代理打官司;委托是一种
47、类型委托是一种类型,即它与即它与class,interface,struct,enum处处于同一级别于同一级别,而且它是引用类型;而且它是引用类型;任何委托类型都是任何委托类型都是system.delegate类的派生类。类的派生类。4.7 委托委托何时使用委托?何时使用委托?(1)回调函数;)回调函数;(2)多线程编程中使用委托来指定启动一个线程时调用的方)多线程编程中使用委托来指定启动一个线程时调用的方法;法;(3)C#中的事件模型。用它们指明处理给定事件的方法。中的事件模型。用它们指明处理给定事件的方法。4.7 委托委托委托用法步骤:委托用法步骤:(1)定义委托)定义委托访问修饰符访问修
48、饰符 delegate 代理方法的返回值类型代理方法的返回值类型 委托类型名(代理方委托类型名(代理方法参数列表)法参数列表)(2)声明委托变量)声明委托变量 委托类型名委托类型名 委托对象;委托对象;(3)实例化委托变量)实例化委托变量委托对象委托对象=new 委托类型(对象名委托类型(对象名.方法名)方法名)/调用某类的实例方法调用某类的实例方法委托对象委托对象=new 委托类型(类名委托类型(类名.方法名)方法名)/调用某类的静态方法调用某类的静态方法(4)调用委托,实现方法)调用委托,实现方法 委托对象(实参)委托对象(实参)实例化时必须指定实例化时必须指定方法名方法名4.7 委托委托
49、Void Multiply(int,int).Void Divide(int,int).可以引用任何方法,将在运行时决定委托和方法必须具有相同的签名-public delegate void Call(int num1,int num2);-4.7 委托委托定义委托定义委托namespace Delegates public delegate int Call(int num1,int num2);class Math public int Multiply(int num1,int num2)return num1*num2;public int Divide(int num1,int nu
50、m2)return num1/num2;class TestDelegates public static void Main()Call objCall;Math math=new Math();objCall=new Call(math.Multiply);Console.WriteLine(“乘积是:乘积是:”+objCall(1,2);将方法与委托关联起来4.7 委托委托回调函数回调函数namespace Delegates public delegate int Call(int num1,int num2);class Math public int Multiply(int nu