第四面向对象编程进阶.ppt

上传人:sccc 文档编号:4871682 上传时间:2023-05-20 格式:PPT 页数:67 大小:1.61MB
返回 下载 相关 举报
第四面向对象编程进阶.ppt_第1页
第1页 / 共67页
第四面向对象编程进阶.ppt_第2页
第2页 / 共67页
第四面向对象编程进阶.ppt_第3页
第3页 / 共67页
第四面向对象编程进阶.ppt_第4页
第4页 / 共67页
第四面向对象编程进阶.ppt_第5页
第5页 / 共67页
点击查看更多>>
资源描述

《第四面向对象编程进阶.ppt》由会员分享,可在线阅读,更多相关《第四面向对象编程进阶.ppt(67页珍藏版)》请在三一办公上搜索。

1、第四章 面向对象编程进阶,本章学习目标,理解类的继承与多态的概念熟悉类型转换的方法掌握结构与接口的定义及用法掌握异常处理的方法掌握委托的定义及用法,第四章 面向对象编程进阶,4.1 类的继承与多态4.3 类型转换4.4 结构与接口4.6 异常处理4.7 委托,4.1 类的继承与多态,4.1.1 继承4.1.2 多态,4.1.1 继承,类的继承性:C#允许基于某一个已经定义的类来创建一个新类。基类:被继承的类,即父类。派生类:继承的类,即子类。,4.1.1 继承,访问修饰符 class 类名:基类 类主体 访问修饰符:public:表示不限制对类的访问;internal:可被同一个项目的程序访问

2、;sealed:表示一个密封类,不能被继承。说明:如果对类不指定访问修饰符,则类的默认访问修饰符为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类,则C类具有B类和A类的成员;派生类是对基类的扩展,派生类定义中可以声明新的成

3、员;派生类定义中如果声明了与基类同名的成员,则基类的同名成员将被隐藏,从而使派生类不能直接访问同名的基类的成员;基类可以定义虚方法成员等,这样派生类能够覆盖这些成员以表现类的多态性。,类的继承规则,4.1.1 继承,派生类构造函数,默认执行基类的无参构造函数,如果要执行基类有参构造函数,则必须在派生类构造函数的基表列表中指出;构造函数调用顺序:先基类后派生类。,派生类析构函数,析构函数调用顺序:先派生类后基类。,4.1.1 继承base,在派生类中调用基类方法在构造函数中显式调用基类构造函数 public 派生类名(形参列表):base(基类构造函数实参列表)在方法中调用基类方法 base.基

4、类方法名(参数表),4.1.1 继承隐藏,隐藏自动隐藏与基类同名的成员声明成员时,显式使用new修饰符,隐藏实质上是使继承的成员在派生类成为不可见的。隐藏的成员并没有被删除,只是不能从派生类直接访问,通过基类能够直接访问它。,4.1.2 多态,编译时实现的多态:如果一个类中有两个或两个以上的方法的名字相同,而它们的形参个数或形参类型有所不同,在程序编译时能够正确区别他们;运行时实现的多态:指在程序运行时,基类对象执行一个基类与派生类都具有的同名方法调用时,程序可以根据基类对象类型的不同(基类还是派生类)进行正确的调用。实现方法:虚方法、抽象方法,4.1.2 多态虚方法,public virtu

5、al 返回类型 方法名(参数列表)方法体,基类中定义虚方法,public override 返回类型 方法名(参数列表)方法体,派生类中重写基类中定义虚方法,4.1.2 多态虚方法,几点说明:基类与派生类中的方法名、参数列表、返回类型必须完全一致;可被重写的基类方法是虚方法、抽象方法或重写方法(override修饰)virtual不能与static、abstract或override中任一个同时出现;override不能与new、static、virtual或abstract中任一个同时使用;,4.1.2 隐藏与多态实例,隐藏与多态,class A public void E()Console

6、.WriteLine(“A.E”);public void F()Console.WriteLine(“A.F”);public virtual void 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

7、=b;a.E();b.E();a.F();b.F();a.G();b.G();,输出结果:A.EB.EA.FB.FB.GB.G,父类可以引用子类对象,父类引用只能调用子类继承自父类的方法,父类不能调用子类独有的方法。,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(“

8、C.F”);class D:C public 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.F,4.1.2 多态抽象类与抽象方法,抽象类:是一种特殊的基类,该类并不与具体的事物发生联系;例如几何体,计算几何体体积的方法不可能有具体实现过程,只有具体某一种几何体才有求体积的方法;抽象类是指在基类的定义中声明不包含任何实现代码的方法,实际上就是一个不

9、具有任何具体功能的方法,即抽象方法。该方法的唯一作用就是让派生类来重写;在基类定义中,只要类体中包含一个抽象方法,该类即为抽象类。,4.1.2 多态抽象类与抽象方法,public abstract class 类名 public abstract 返回类型 方法名称(参数列表);,声明抽象类与抽象方法,不包含方法体,也不能要,4.1.2 多态抽象类与抽象方法,抽象类几点说明一个类中只要包含一个抽象方法,该类即为抽象类;反之,一个抽象类中必须包含抽象方法;抽象类中可以包含非抽象方法;抽象类不能实例化,不能用new生成实例;抽象类不能被密封。派生类说明如果基类为抽象类,则要求派生类必须重载实现基类

10、中所有抽象方法。抽象方法说明抽象方法没有方法体,只有一个方法头后跟一个分号;抽象方法被隐含认为是一种虚方法,派生类中必须重写所有抽象方法,且重写的方法与抽象方法的参数及类型、方法名都应相同。,4.1.2 多态抽象类与抽象方法,public abstract class Shape protected double x;protected double y;protected double z;public Shape(double dx,double dy,double dz)x=dx;y=dy;z=dz;public abstract double Cubage();,定义抽象类及抽象方法,

11、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;,重载抽象方法,4.1.2 多态抽象类与抽象方法,虚方法与抽象方法区别抽象方法必须在抽象类中定义,虚方法可以在抽象类或一般类中定义;在基类中,虚方法用virtual关键字,抽象方法用abstract关键字;在派生类中,虚方法不一定重写,抽象方法一定要重写;,修饰符小结,基类方法,abstract,virtu

12、al,override,无说明符,new(无说明符),override,派生类方法,4.1.2 多态密封类和密封方法,密封类:不允许被继承的类。,定义密封类,访问修饰符 sealed class 类名称 类体,public sealed class SealedClass public string method()return 我是密封类;,定义密封类,4.1.2 多态密封类和密封方法,基类中要密封的方法必须有virtual、abstract或override派生类中的密封方法必须同时有sealed override。,定义密封方法,访问修饰符 sealed override 返回类型 方法

13、名(参数列表)方法体,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 Test public static void Main()C c=new C();c.F();,sealed必须与override同时出现,不允许重写F方法若

14、无override则为隐藏,4.3 类型转换,4.3.1 隐式类型转换4.3.2 显式类型转换4.3.3 使用Convert转换,为什么需要类型转换,编译器要确切地知道数据的类型,int num=123;,整数,字符串,需要类型转换!,编译出错,4.3.1 隐式类型转换,隐式转换:自动类型转换,float,int,规则:对于数值类型,A的取值范围完全包含在B内,A,B,static void Main(string args)double score=58.5;/原始成绩 int bonus=2;/加分 int sum;/总分 sum=score+bonus;/计算总分 Console.Wri

15、teLine(sum);Console.ReadLine();,4.3.2 显式类型转换,static void Main(string args)double score=58.5;int bonus=2;int sum;sum=(int)score+bonus;Console.WriteLine(sum);Console.ReadLine();,明确告诉编译器转换类型注意:double(58.5)-int(58),精度可能丢失!,显式转换:强制类型转换,使用 Parse()进行转换,字符串和数值型的互相转换,int,float,double,string,int.Parse(),float

16、.Parse(),double.Parse(),ToString(),必须是数字的有效表示形式!,4.3.3 使用 Convert 类进行转换,使用 Convert:Convert.ToXxx(object value),Convert.ToInt32(),Convert.ToSingle(),Convert.ToString(),double85.63,string85.63,int86,float85.63,Parse 与 Convert,Xxx.Parse(string),目标类型的有效表示形式,Convert.ToXxx(object):,注:Xxx表示某种类型,字符串,其他类型,任意

17、类型,其他类型,4.4 结构与接口,访问修饰符struct 结构名 结构主体 访问修饰符:public:表示不限制对结构的访问;internal:可被同一个项目的程序访问(默认);结构成员包括字段、属性、方法等;结构可以定义构造函数,但不能定义析构函数;有一个默认的不带参数的构造函数,用于对结构的字段进行初始化,并且结构的默认构造函数不能被重写。,结构的声明,4.4 结构与接口,结构与类的区别,4.4 结构与接口,struct account public string name;public double balance;public account(string n,double b)na

18、me=n;balance=b;,结构定义及使用(一),4.4 结构与接口,结构定义及使用(一)续,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”)

19、;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;Console.WriteLi

20、ne(“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 结构与接口,接口声明定义了一个协定,使用接口的类或结构必须遵守其协定。接口可以从多个基接口继承,而类或结构可以实现多个接口;接口成员只能是方法、属性、索引和事件,不能有字段。接口本身不提供它所定义成员的实现代码

21、,只指定实现该接口的类或结构必须提供的成员的调用形式。,4.4 结构与接口,访问修饰符 interface 接口名:基接口1,基接口2.接口体 访问修饰符:public:表示不限制对类的访问;internal:可被同一个项目的程序访问(默认);接口成员包括属性、方法等;接口不能包括字段,也不能定义构造函数和析构函数;接口成员访问修饰符默认为public;接口的命名通常是以I开头,如IPartA。,接口的声明,4.4 结构与接口,接口的实现函数成员的实现:类、结构;实现接口类型:public成员实现显示接口成员实现不能用new操作符创建接口的实例,4.4 结构与接口,public成员实现实现接口

22、成员时,声明成员为public,这样的实现声明称为public接口成员实现声明,简称public成员实现或public实现;public实现的成员具有双重访问性,因为它是接口成员的实现,所以可以通过接口实例来访问,又因为它是public成员,还可以通过类或结构的实例来访问。,4.4 结构与接口,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 结构

23、与接口,public成员实现(二),interface IPoint int Xget;set;int Yget;set;class MyPoint:IPoint private int myX,myY;public MyPoint(int 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

24、 void PrintPoint(IPoint p)Console.WriteLine(“x=0,y=1”,p.X,p.Y);public static void Main()MyPoint p=new MyPoint(2,3);Console.Write(“MyPoint:”);PrintPoint(p);,public成员实现(二)续,输出结果:MyPoint:x=2,y=3,4.4 结构与接口,显式接口成员实现用接口成员的完全限定名(接口名.成员名)来显式指定要实现的接口成员,这样的实现声明称为显式接口成员实现声明,简称显式实现声明;注意:显式实现声明中不能用public修饰符。,4.4

25、 结构与接口,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.WriteLine(“B.p”);public void p()

26、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.p,4.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,IA public static void Main()B b=new B();IA a

27、=b;a.p();/显式接口成员实现优先 C c=new C();a=c;c.p();a.p();,显式成员实现(三),输出结果:A.pB.pA.p,类可以同时有一个基类和零个以上的接口,并将基类写在前面,4.6 异常处理,异常指由于程序运行时发生的错误,从而导致程序错误结束。异常处理 当程序运行过程中发生了某个异常现象,系统将产生一个相应的异常类对象,并把它交给系统处理,系统负责找到处理错误的代码并执行,如除数为0。,4.6 异常处理,使用语句或表达式在执行过程中自动引发了某个异常的条件,使得操作无法正常结束,从而引发异常;使用显式 throw 语句来引发异常。在此情况下,控制权将无条件转到

28、处理异常的部分代码。,引发异常两种方式,C#中异常处理语句,trycatch trycatchfinally tryfinally throw,4.6 异常处理,try 被监控的可能发生异常的程序代码catch(异常类名 异常变量名)异常处理,格式1,try 被监控的可能发生异常的程序代码finally 最终要执行的代码,格式2,try 被监控的可能发生异常的程序代码catch(异常类名 异常变量名)异常处理finally 最终要执行的代码,格式3,4.6 异常处理,try子句包含可能引起异常的代码;只有发生异常时才执行catch子句,若没有异常,try子句正常结束,catch子句被忽略,程序

29、转到catch后的第一条语句开始执行;可以包含多个catch语句;catch子句可以不包括参数,它将捕获所有类型的异常;异常类名必须为System.Exception或从System.Exception派生的类型;finally子句不管有没有异常都执行。,4.6 异常处理,4.6 异常处理,int num1,num2,result;try num1=int.Parse(Console.ReadLine();num2=int.Parse(Console.ReadLine();result=num1/num2;Console.WriteLine(“商是”+result);catch(DivideB

30、yZeroException error)Console.WriteLine(除数不能为零!);catch(FormatException error)Console.WriteLine(输入格式错误!);catch(Exception ex)/如果写,写在catch的最后 Console.WriteLine(“输入错误”);finally Console.WriteLine(谢谢使用!);,异常处理,4.6 异常处理,throw异常处理,static int Divide(int x,int y)try int z=x/y;return z;catch(DivideByZeroExcepti

31、on error)throw new DivideByZeroException(“除数不能为0”);,static void Main()int num1,num2,result;try num1=int.Parse(Console.ReadLine();num2=int.Parse(Console.ReadLine();result=Divide(num1,num2);Console.WriteLine(“商是”+result);catch(DivideByZeroException error)Console.WriteLine(error.Message);catch(FormatEx

32、ception error)Console.WriteLine(输入格式错误!);catch(Exception ex)Console.WriteLine(“输入错误”);finally Console.WriteLine(谢谢使用!);,4.7 委托,委托也叫代理,就是把事情交给别人去办,如委托律师代理打官司,委托同学代买火车票;C#中如果将一个方法委托给一个代理对象,那么这个对象就可以全权代理这个方法的执行;使用委托首先要定义委托,声明委托能代理什么类型的方法,就像房产中介能代理抵押贷款业务,而不能代理打官司;委托是一种类型,即它与class,interface,struct,enum处于

33、同一级别,而且它是引用类型;任何委托类型都是system.delegate类的派生类。,4.7 委托,何时使用委托?(1)回调函数;(2)多线程编程中使用委托来指定启动一个线程时调用的方法;(3)C#中的事件模型。用它们指明处理给定事件的方法。,4.7 委托,委托用法步骤:(1)定义委托访问修饰符 delegate 代理方法的返回值类型 委托类型名(代理方法参数列表)(2)声明委托变量 委托类型名 委托对象;(3)实例化委托变量委托对象=new 委托类型(对象名.方法名)/调用某类的实例方法委托对象=new 委托类型(类名.方法名)/调用某类的静态方法(4)调用委托,实现方法 委托对象(实参)

34、,实例化时必须指定方法名,4.7 委托,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 Di

35、vide(int num1,int num2)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 M

36、ultiply(int num1,int num2)return num1*num2;public int Divide(int num1,int num2)return num1/num2;class TestDelegates public static void Main()Call objCall1,objCall2;Math math=new Math();objCall1=new Call(math.Multiply);objCall2=new Call(math.Divide);int mul=Process(2,2,objCall1);int div=Process(2,2,o

37、bjCall2);Console.WriteLine(“乘积是:”+mul);Console.WriteLine(“商是:”+div);public static int Process(int num1,int num2,Call calculate)return calculate(num1,num2);,4.7 委托,delegate声明中的“返回值类型”要与方法返回类型一致;delegate声明中的“参数列表”要与方法的形参形表一致;在委托的“实例化”的时候必须传入一个方法名。这个方法名就是该代理指向的方法。,委托要点:,4.7 委托多播,相对于一次委托只调用一个方法,一次委托也可以调

38、用多个方法,称为多播;通过+=和-=运算符(或+、-)实现多播的增加或减少;如果调用多播委托,就可以按顺序连续调用多个方法。为此,委托的返回值类型就必须返回 void(否则,返回值应送到何处?)。,4.7 委托多播,多播委托,namespace Delegates public delegate int Call(int num1,int num2);class Math public int Multiply(int num1,int num2)Console.WriteLine(“乘积是”+num1*num2);public int Divide(int num1,int num2)Console.WriteLine(“商是”+num1/num2);class TestDelegates static void Main()Call objCall;Math math=new Math();objCall=new Call(math.Multiply);objCall+=math.Divide;objCall(2,2);,将方法添加到委托列表,总结,C#中类的继承与多态?C#中接口的定义及使用?C#中如何处理异常?C#中的委托?,

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

当前位置:首页 > 建筑/施工/环境 > 农业报告


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号