面向对象高级特性xm.ppt_第1页
面向对象高级特性xm.ppt_第2页
面向对象高级特性xm.ppt_第3页
面向对象高级特性xm.ppt_第4页
面向对象高级特性xm.ppt_第5页
已阅读5页,还剩64页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C#高级编程,调试,应用程序开发,可以安装在客户端机器上,应用程序必须,无错误 无故障 可靠 稳健,查找和排除错误或故障称为调试,调试的必要性,计算机化的计费系统,在事物处理过程中,系统显示错误消息,必须重新输入全部信息,在部署应用程序前必须先对其进行调试,错误类型,错误类型,语法错误,逻辑错误,运行时错误,语法错误、缺少括号等 在编译时确定 易于确定,错误的算法导致错误结果、公式错误等 在执行过程中确定 难以调试,内存泄漏、以零作除数、异常 在运行时确定 难以调试,调试过程,调试器,观察程序的运行时行为,跟踪变量的值,确定语义错误的位置,查看寄存器的内容,查看内存空间,调试过程,暂停,可在代码中插入“断点”,以便在特 定行处暂停执行该代码,调试过程,右键单击所需代码行,以设置断点,选择“插入断点”,调试过程,选择“调试” “继续”以便继续执行程序,调试过程,.NET 集成开发环境,Debug模式,Release模式,VS.NET 中的调试工具,“局部变量”窗口,VS.NET 中的调试工具,“监视”窗口,VS.NET 的调试工具,“快速监视”对话框,VS.NET 中的调试工具,“即时”窗口,VS.NET 中的调试工具,跨语言调试 调试使用 .NET 框架编写的应用程序以及 Win32 本机应用程序 加入正在运行的程序 调试多个程序,Visual Studio .NET 调试器的功能,异常,网上银行,某学生小王转帐5000到其朋友小李的帐面上,0,4500,数据库,系统将查询发送到数据库中,tranfer_money() sendquery(); . .,余额 4500-5000,程序崩溃,拒绝交易,“C#”中的异常,C# 中的异常处理,. INPUT Divisor IF Divisor = 0 THEN Result = Divident/Divisor ,代码片段 1,输入除数,结果 =,_,0,2,4,GOTO PREVIOUS LINE,触发异常处理程序,C# 中的异常处理,. INPUT Divisor Result = Divident/Divisor ,代码片段 1,“用户自定义”错误检查机制,难以检查输入的任何“特殊字符”,IF Divisor = 0 THEN GOTO PREVIOUS LINE IF Divisor 0 THEN PRINT “无效输入”,运行库,运行库应当提供“错误检查机制”,错误与异常,错误:可预见,如信用卡号格式不对或口令不对。可由程序代码进行排除。 异常:与程序无关的外部原因造成。如数据表不可用或硬件故障等。,System.Exception,System.Exception,System.Exception,在 C# 程序中,引发异常共有以下两种方式,使用显式 throw 语句来引发异常。在此情况下,控制权将无条件转到处理异常的部分代码 使用语句或表达式在执行过程中激发了某个异常的条件,使得操作无法正常结束,从而引发异常,Try.Catch.Finally,try 和 catch 块,滤水器,filter_water() try water(); catch impurities.Show(); . .,过滤水,杂质,/程序代码,/错误处理代码,try /程序代码 catch (IOException E) /错误处理代码 ,try 和 catch 块,try /程序代码 catch (IOException E) /错误处理代码 ,引发I/O 设备异常,try 和 catch 块,try /程序代码 catch( E) /错误处理代码 ,可处理系统中的任何一种异常,System.Exception,try 和 catch 块,if (grade 150) throw new InvalidNumberInput (grade+ “不是合法的成绩”); ,throw 可用来引发自定义异常“InvalidNumberInput”,使用 finally,try /程序代码 catch /错误处理代码 finally /finally 代码 ,无论有否异常该代码都会执行,多重 catch 块,try /程序代码 catch (IOException E) /错误处理代码 catch (OutOfMemoryException E) /错误处理代码 ,用于捕捉两种异常的“catch”块,using System; public class TestExcep public static int Calc(int j) return 100 / j; class MyApp public static void Main() TestExcep exTest = new TestExcep(); try int dZero = TestExcep.Calc(0); Console.WriteLine(“Result: 0“, dZero); catch (DivideByZeroException ex) Console.WriteLine(“ex.Message: 0“, ex.Message); Console.WriteLine(“ex.Source: 0“, ex.Source); Console.WriteLine(“ex.TargetSite: 0“, ex.TargetSite.ToString(); Console.WriteLine(“ex.StackTrace: 0“, ex.StackTrace); catch (Exception ex) Console.WriteLine(“General “ + ex.Message); finally Console.WriteLine(“Cleanup occurs here“); ,ex.Message: 试图除以零。 ex.Source: 005 ex.TargetSite: Int32 Calc(Int32) ex.StackTrace: 在 TestExcep.Calc(Int32 j) 位置 E:我的桌面临时文件夹实验编程 C Sharp005Program.cs: 行号 96 在 MyApp.Main() 位置 E:我的桌面临时文件夹实验编程C Sharp005Program.cs:行号 107 Cleanup occurs here 请按任意键继续. . .,如何创建定制异常类,using System; public class NoDescException : ApplicationException public NoDescException() public NoDescException(string message) : base(message) public NoDescException(string message, Exception innerEx) : base(message, innerEx) public interface IFun1 string ShowMe(); public interface IFun2 string ShowMe(); class Circle : IFun1 public string ShowMe() return “Circle-IFun1“; public class ObjShowMe public static void ShowMe(object obj) if (!(obj is IFun1 ,未处理异常,当CLR找不到处理异常的catch过滤器时 using System; class MyApp public static void Main() try int dZero = 1/0; finally Console.WriteLine(“finally“); ,定制处理未处理异常,终止应用程序之前记录有关异常的信息。如果有足够的有关应用程序状态的信息,则可以采取其他措施,如保存程序数据以便于以后进行恢复。 建议谨慎行事,因为未处理异常时可能会损坏程序数据。 没有通用的方法适用于所有C#程序。 Windows窗体应用: Applicatioin.ThreadException += new ThreadExceptionEventHandler(method); Windows控制台应用: Thread.GetDomain().UnhandledException += new UnhandledExceptionEventHandler(method);,using System; public class TestExcep public static int Calc(int j) return 100/j; public class UnForgiven public static void MyUnhandleMethod(object sender, UnhandledExceptionEventArgs e) #if DEBUG Console.WriteLine(“Debug: “ + e.ToString(); #else Console.WriteLine(“Release: “ + e.ToString(); #endif class MyApp public static void Main() Thread.GetDomain().UnhandledException += new UnhandledExceptionEventHandler(UnForgiven.MyUnhandleMethod); try int dZero = TestExcep.Calc(0); finally Console.WriteLine(“a“); s,定制类中实现System.Object方法,ToString():默认情况下,返回类名。应覆盖此方法,显示出对象与访类其他实例不同的特有内容。 Equals():定制类需定义“相等”的含义:可能两个对象有相同的字段值变相等,也可能引用了相同的内存地址才相等。,定制ToString(),默认返回. 定制ToString方法实例: using System.Text; using System; public class Chair private double myPrice; private string myVendor, myID; public Chair(double price, string vendor, string sku) myPrice = price; myVendor = vendor; myID = sku; public override string ToString() StringBuilder chairSB = new StringBuilder(); chairSB.AppendFormat(“ITEM = Chair“); chairSB.AppendFormat(“tVENDOR = 0“, myVendor); chairSB.AppendFormat(“tPRICE = 0“, myPrice.ToString(); return chairSB.ToString(); static void Main() Chair myChair = new Chair(120.0, “Broyhill“, “60-1222“); Console.WriteLine(myChair.ToString(); ,定制Equals(),比较两个引用类型的对象时,当它们指向相同的对象,返回true。 如果基于值来比较对象时,必须覆盖该方法。String类就是这样一个例子,其虽然是引用类型,但它会基于字符串中的字符串完成比较。,using System; public class Chair private double myPrice; private string myVendor, myID; public Chair(double price, string vendor, string sku) myPrice = price; myVendor = vendor; myID = sku; public override bool Equals(object obj) if (obj = null) return false; if (this.GetType() != obj.GetType() return false; Chair otherObj = (Chair)obj; if (!myVendor.Equals(otherObj.myVendor) return false; if (!myPrice.Equals(otherObj.myPrice) return false; if (!myID.Equals(otherObj.myID) return false; return true; public override int GetHashCode() return myID.GetHashCode(); static void Main() Chair myChair = new Chair(120.0, “Broyhill“, “60-1222“); Chair newChair = new Chair(120.0, “Broyhill“, “60-1222“); bool eq = myChair.Equals(newChair); Console.WriteLine(eq.ToString(); ,覆盖GetHashCode(),GetHashCode方法为对象生成一个Int32类型的散列码。.NET要求两个相同的对象必须有相同的散列码,不同的对象不保证有不同的散列码。 Equals方法必须和GetHashCode方法成对出现。,克隆来创建对象副本,Object中的MemberwiseClone():默认返回对象的一个副本,是一种浅拷贝。 可以实现自已的克隆方法进行深拷贝。 不能克隆基本类型。可克隆的类必须实现ICloneable接口。 public interface ICloneable Object Clone(); ,using System; public class Chair : ICloneable private double myPrice; private string myVendor, myID; public Upholstery myUpolstery; public Chair(double price, string vendor, string sku) myPrice = price; myVendor = vendor; myID = sku; public Object Clone() return MemberwiseClone(); public class Upholstery public string fabric; public Upholstery(string fab) fabric = fab; class MyApp static void Main() Chair myChair = new Chair(120.0, “Broyhill“, “60-1222“); Chair chairClone = (Chair)myChair.Clone(); bool isEqual; isEqual = Object.ReferenceEquals(myChair, chairClone); Console.WriteLine(isEqual.ToString(); isEqual = Object.ReferenceEquals(myChair.myUpolstery, chairClone.myUpolstery); Console.WriteLine(isEqual.ToString(); ,什么是序列化,Profile对象,界面语言:英语,RssFeed对象,存储 介质,存储,序列化是将对象的状态存储到特定存储介质中的过程,代理服务器,特性,Serializable abstract class FeedBase,标识这个类是可序列化的,可序列化就是这个类的一个特性,描述性关键字 对程序中的元素如:类、字段、方法、属性 命名时以Attribute结尾: SerializableAttribute 使用时省略Attribute,public sealed class SerializableAttribute,特性其实是一个类,可在类成员附加NonSerialized属性,将其排除在串行化范围之外。 public class Chair NonSerialized public double myPrice; public string myVendor, myID; public Chair() public Chair(double price, string vendor, string sku) myPrice = price; myVendor = vendor; myID = sku; ,使用序列化,fileStream = new FileStream(“profile.bin“, FileMode.Create); BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(fileStream, Profile);,Serializable abstract class FeedBase,要存储的对象标记为可序列化,包括他的父类和属性的类,使用二进制方式存储对象,二进制格式化器,将对象以二进制方式格式化为流,Serialize ( Stream serializationStream, Object graph),流,对象,Serialize的用法:,序列化的过程,格式化程序,对象可否序列化,子类成员 可否序列化,将对象格式化,写入存储介质,异常退出,序列化对象中的子类成员,Y,Y,N,N,反序列化,把Profile对象存储成文件,怎么取出来呢?,读取,反序列化则是从特定存储介质中的数据重新构建对象的过程,存储 介质,Profile对象,界面语言:英语,RssFeed对象,代理服务器,数据转换为对象,使用反序列化,将序列化好的Profile数据反序列化为对象,fileStream = new FileStream(“profile.bin“, FileMode.Open); BinaryFormatter bf = new BinaryFormatter(); Profile = (Profile)bf.Deserialize(fileStream);,将指定流反序列化,类型转换,public Object Deserialize ( Stream serializationStream ),Deserialize的用法:,流,对象,需要类型转换,using System; using System.Runtime.Serialization.Formatters.Binary; using System.IO; Serializable public class Chair public double myPrice; public string myVendor, myID; public Chair() public Chair(double price, string vendor, string sku) myPrice = price; myVendor = vendor; myID = sku; class MyApp static void Main() Chair myChair = new Chair(100.0, “Broyhill“, “10-09“); FileStream fs = new FileStream(“C:chairs.dat“, FileMode.Create); BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(fs, myChair); fs.Close(); Chair newChair = new Chair(); fs = new FileStream(“C:chairs.dat“, FileMode.Open); newChair = (Chair)bf.Deserialize(fs); Console.WriteLine(newChair.myPrice.ToString() + “ “ + newChair.myVendor + “ “ + newChair.myID); ,串行化事件,这些事件处理程序在被串行化的对象中实现,必须满足以下两个要求: 必须为方法附加与事件相关的属性 方法必须有以下签名: void (StreamingContext context) 例如: OnDeSerialized void OnMyDeserialized(StringContext context) 注:需加上using System.Runtime.Serialization;,处理串行化对象的版本变化,如果删除了原对象的一个字段,格式化器只是忽略逆串行化流中的多余数据。,Serializable public class Chair public double myPrice; public string myVendor, myID; . ,Serializable public class Chair public string myVendor, myID; ,如果原对象增加了新字段,格式化器发现新字段后,会抛出异常(.NET2.0)。,Serializable public class Chair public double myPrice; public string myVendor, myID; . ,Serializable public class Chair public string myVendor, myID; ,可以为新字段附加OptionalField属性。格式器会为新字段指定一个默认值。,Serializable public class Chair OptionalField public double myPrice; public string myVendor, myID; . ,还可以利用逆串行化事件为新字段赋值。 OnDeserialized void OnMyDeserialized(StreamingContext context) if(myVendor = “Lane”) finish=“OaK”; else finish=“Cherry”; ,反射,可以ILDasm反编译工具浏览一个dll和exe的构成,这种机制叫做反射(Reflection),应用程序或dll,类的属性,类的方法,应用程序信息,用于在运行时通过编程方式获得类型信息,反射,现场演示,通过代码演示获取dll的版本号,using System.Reflection;,class Program static void Main(string args) string version = Assembly.LoadFile(“D:MyNewsReader.exe“) .GetName().Version.ToString(); Console.WriteLine(version); ,引入命名空间,反射,什么是设计模式,模式就是得到很好研究的范例,走为上,围魏救赵,声东击西,设计模式是软件开发过程中经验的积累 特定问题的经过实践检验的特定解决方法,简单工厂模式,简单工厂模式的原理,简单工厂模式,工厂类:担任这个角色的是工厂方法模式的核心,含有与应用紧密相关的商业逻辑。工厂类在客户端的直接调用下创建产品对象,它往往由一个具体的类实现。 抽象产品角色:担任这个角色的类是由工厂方法模式所创建的对象的父类,或她们共同拥有的接口。一般由接口或抽象类实现。 具体产品角色:工厂方法模式所创建的任何对象都是这个角色的实例,由具体类实现。,简单工厂模式优缺点,模式的核心是工厂类,这个类负责产品的创建,而客户端可以免去产品创建的责任,这实现了责任的分割。但由于工厂类集中了所有产品创建逻辑的,如果不能正常工作的话会对系统造成很大的影响。如果增加新产品必须修改工厂角色的源码。,设计模式的意义,提高软件的可复用性,灵活,适应软件设计的变化,面向对象在实际应用中集中体现,简单工厂模式实例,父类产品,子类产品A,子类产品C,工厂,客户,public interface IApparel string ShowMe(); ,public class SportShirt: IApparel public string ShowMe() return (“Sports Shirt”); ,public class DressShirt: IApparel public string ShowMe() return (“Dress Shirt”); ,public class ApparelFactory public IApparel CreateApparel (string apptype) switch(apptype) case “DRESSSHIRT”: return new DressShirt(); case “SPORTSSHIRT”: return new SportsShirt(); return null; ,ApparelFactory = new ApparelFactory(); IApparel obj1 = factory.CreateApparel(“DRESSSHIRT”); IApparel obj2 = factory.CreateApparel(“SPORTSSHIRT”); string shirtType = obj1.ShowMe();,为什么需要抽象工厂设计模式,:简单工厂设计模式原理结构,什么是抽象工厂设计模式,什么是抽象工厂设计模式,:抽象工厂设计模式原理结构,什么是抽象工厂设计模

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论