版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第一讲 C#入门目录CONTENTS课程简介.NET基础知识VisualStudio2012集成开发环境C#的基本语法概述1234目录CONTENTS课程简介.NET基础知识VisualStudio2012集成开发环境C#的基本语法概述12341.1课程简介(1/3)讲课28学时,上机20学时成绩组成:平时30%(考勤+半期+实验)+期末70%半期、期末均为开卷考试半期考试时间:第八次课,预计10月9号,第五周周日下午一二节期末考试时间:第九周11月1号(周二)或4号(周五)交流方式郭奕,电QQ:22545531周四下午,6A-3061.1课程简介(2/3)课程特点:讲授为辅,动手为主注重第二课堂的学习,课前的预习,课后的练习上机练习和课堂教学同步进行平时成绩考评规则:平时成绩每人的基础分为?分——动态分,最高100迟到早退请假等,都会扣除相应分数随时课堂提问,回答正确加分案例教学部分,以分组教学为主,学生讲,老师指导,根据实际情况,学生讲一次,加分5~10分不等。反馈教材中的错误,每个有效反馈+1~5分.案例分析注意事项:1、必须现场从头开始操作各个具体步骤,不允许直接分析已有程序,但可以参考。2、每一步骤必须解释,可以直接拷贝代码,不用现场敲,但必须至少对每个函数进行解释,甚至解释到重要语句。3、可以5个人组队,每个抽到的人的队伍中负责主讲的人来讲,但必须说明队员组成以及每个人的工作区分。1.1课程介绍(3/3)第一部分:.NET程序设计基础(2学时理论+2学时上机)第二部分:面向对象程序设计基础(4学时理论+2学时上机)第三部分:基于C#的数据结构(2学时理论)第四部分:案例教学(18学时理论+16学时上机)包括GUI程序设计、多媒体程序设计、文件操作、多线程操作、网络通信、数据库操作、和硬件的交互等要求同学分组预先实现,上课的时候来分享第五部分:半期考试(2学时)目录CONTENTS课程简介.NET基础知识VisualStudio2012集成开发环境C#的基本语法概述12341.2.NET基础知识1.2.1.NET框架1.2.2C#和.NET1.2.3.NET程序的编译1.2.4C#语言及其特点1.2.1.NET框架结构.NET平台包括.NET框架和.NET开发工具组成。.NET框架是整个开发平台的基础,包括公共语言运行时(CommonLanguageRuntime,CLR)和.NET类库。公共语言运行时类似于Java虚拟机,负责内存管理和程序执行,是.NET的基础。.NET类库是一个与公共语言运行时紧密集成的可重用的类型集合。.NET开发工具包括VisualStudio.NET集成开发环境和.NET编程语言。.NET编程语言包括VisualBasic、VisualC++和新的VisualC#等,用来创建运行在公共语言运行时上的应用程序。1.2.2C#和.NET的关系C#是Microsoft公司在C++和Java两种编程语言的基础上针对Microsoft.NET框架开发的一种语言。C#语言是一种简单、现代、优雅、面向对象、类型安全、平台独立的新型组建编程语言。C#编写的所有代码总是在Microsoft.NETFramework中运行。C#就其本身而言只是一种语言,尽管它是用于生成面向.NET环境的代码,但它本身不是.NET的一部分。C#程序需要在.NETFramework上运行。1.2.3.NET程序的编译1.2.4C#语言及其特点C#语言具有如下一些特点:语言简洁。保留了C++的强大功能。快速应用开发功能。语言的自由性。强大的Web服务器控件。支持跨平台。与XML相融合。1.2.4C#语言及其特点C#和C++的主要区别:编译目标内存管理指针字符串库继承托管代码和非托管代码以运行库为目标的代码称为托管代码,而不以运行库为目标的代码称为非托管代码目录CONTENTS课程简介.NET基础知识VisualStudio2012集成开发环境C#的基本语法概述12341.3VisualStudio2012集成开发环境VisualStudio2012的版本:Ultimate2012withMSDN旗舰版Premium2012withMSDN高级版Professional2012withMSDN专业版Professional2012专业版TestProfessional2012withMSDN测试专业版VisualStudioExpress2012forWebVisualStudioExpress2012forWindows8VisualStudioExpress2012forWindowsDesktopVisualStudioExpress2012forWindowsPhone集成开发环境的使用创建项目管理项目中的资源使用工具箱使用类视图使用属性页目录CONTENTS课程简介.NET基础知识VisualStudio2012集成开发环境C#的基本语法概述12341.4C#基本语法概述1.4.1C#程序组成和基本编码规则1.4.2主要数据类型1.4.3简单的流程控制方法1.4.1C#程序组成和基本编码规则usingSystem;classHello{ staticvoidMain(){ Console.WriteLine("Hello,World"); Console.ReadKey(); }}C#程序源文件的扩展名通常都是.cs。Program.cs:程序源文件,通常是程序的入口,简单的程序可以直接在此文件中编写。AssemblyInfo.cs:该文件包含通用程序信息,所以程序集属性都放在此文件中。引用:表示在此项目中引用的程序集。C#严格区分大小写。1.4.1C#的组成关键字命名空间类和方法语句大括号1.4.2主要数据类型常量和变量1.常量常量是程序运行过程中不变的量。在C#中定义常量的方式有两种,一种叫做编译时常量(Compile-TimeConstant),也称为静态常量;另一种叫做运行时常量(RuntimeConstant),也称为动态常量。前者用const来定义,后者用readonly来定义。变量2.变量变量是程序中的基本存储单元,它的定义格式如下:[变量修饰符]类型变量名1[=值1[,变量名2[=值2]…];变量修饰符用来控制变量的可访问性,这些访问属性类似于常量。变量的命名遵循标识符命名规则,变量声明时可以直接赋初值。例如:intcount,x=110;charc='a';在C#中,变量大致有如下类别:静态变量、实例变量、数组、值参数、引用参数、输出参数及局部变量。运算符和表达式对各种类型的数据进行加工的过程称为运算,表示各种不同运算的符号称为运算符,参与运算的数据称为操作数。C#的运算符很丰富按操作数的数目来分有:一元运算符、二元运算符、三元运算符。基本的运算符按功能划分有:算术运算符、关系运算符、布尔运算符、位运算符、赋值运算符及其扩展赋值运算符、条件运算符、其它运算符(包括分量运算符·,下标运算符[],实例运算符is等)。1.4.3简单的流程控制方法分支结构循环结构异常处理分支结构if语句if语句也称为条件语句、选择语句,用于实现程序的分支结构,根据条件是否成立来控制执行不同的程序段,完成相应的功能。主要利用if语句完成程序,创建一个Windows应用程序,先输入年龄值,再判断是否大于18,最后显示判断结果,如果年龄大于18则显示已成年,否则显示未成年。Switch语句switch语句专用于实现多分支结构,其语法更简洁,能处理复杂的条件判断。创建一个Windows应用程序,使用switch语句来计算不同服装的应付款,其中休闲装单价为480一套,西装单价为780一套,皮衣类单价为1300一套。循环语句Whilewhile语句表达的逻辑含义是:当逻辑条件成立时,重复执行某些语句,直到条件不成立时终止,从而不再循环。因此在循环次数不固定时while语句相当有用。编程求1+2+3+…+100的值。Do-whiledo-while语句的特点是先执行循环体,然后判断循环条件是否成立。创建一个Windows应用程序,统计从键盘输入一行字符中英文字母的个数。循环语句for一个百万富翁遇到一个陌生人,陌生人找他谈一个换钱的计划,该项计划如下:我每天给你十万元,而你第一天只需给我一分钱,第二天我仍给你十万元,你给我二分钱,第三天我仍给你十万元,你给我四分钱,…,你每天给我的钱是前一天的两倍,直到满一个月(30天),百万富翁很高兴,欣然接受了这个契约。请编写一个程序计算这一个月中陌生人给了百万富翁多少钱,百万富翁给陌生人多少钱。foreach利用循环嵌套编程实现九九乘法表。跳转语句GotoBreakContinue异常处理异常是程序执行时遇到的任何错误情况或意外行为。以下这些情况都可以引发异常:您的代码或调用的代码(如共享库)中有错误,操作系统资源不可用,公共语言运行库遇到意外情况(如无法验证代码),等等。对于这些情况,应用程序可以从其中一些恢复,而对于另一些,则不能恢复。异常处理旨在为程序可能遇到的异常情况提供控制功能。C#中的结构化异常处理是通过try…catch…finnally语句实现的。try…catch…finnally语句的结构如下:try{…//需要保护的代码段}catch[(异常类型1[标识1])]{…//异常处理代码1}catch[(异常类型2[标识2])]{…//异常处理代码2}[……//其他catch块][finally{…}]//错误处理后,继续执行的代码常见的异常类.NET框架针对系统及应用程序的异常,设计了一个基类System.Exception,所有异常类都继承自这个类。基类Exception下存在两类异常:从SystemException派生的预定义公共语言运行时异常类。
从ApplicationException派生的用户定义的应用程序异常类。在一些特殊的情况下,还可以利用throw语句抛出异常,将异常交给上一层程序来处理。在.NET框架提供的从基类Exception派生的异常类层次结构中,每一个异常类都定义一个特定的异常,在很多情况下只需捕获这些异常。但如果用户希望能以编程方式区分一些错误条件,也可以创建自己的异常类。第二讲
面向对象程序设计基础思考什么是托管代码?什么是非托管代码?请举例说明。编程求1+2+3+……+100的结果?While和do…while的区别?Continue和break的区别?C#中的结构化异常处理是通过什么语句实现的?教材23页富翁与陌生人的问题答案?目录CONTENTS面向对象程序设计的基本概念类和对象属性和方法构造函数和析构函数1234目录CONTENTS面向对象程序设计的基本概念类和对象属性和方法构造函数和析构函数12342.1面向对象程序设计的基本概念2.1.1活字印刷技术2.1.2面向过程的方法和面向对象的方法2.1.3案例分析:日期计算程序2.1.4面向对象程序的基本特性2.1.1从活字印刷看面向对象思想常规的印刷术:不容易维护,灵活性差,不容易扩展,不可复用活字印刷术:可维护、可复用、可扩展、灵活性好在面向对象的编程思想中,需要考虑如何通过封装、继承、多态,把程序的耦合度降低,需要利用恰当的设计模式使得程序更加的灵活,容易修改,并且易于复用活字印刷,是思想的成功,是面向对象的胜利2.1.2面向过程的方法和面向对象的方法“面向过程”(ProcedureOriented)是一种以过程为中心的编程思想。面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步的实现,使用的时候一个一个依次调用。五子棋游戏的面向过程设计思路面向对象程序设计,将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性。面向对象就是把构成问题的事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描述某个事物在整个解决问题的步骤中的行为。五子棋游戏的面向对象程序设计思路:黑白双方棋盘系统游戏规则要加入悔棋的功能怎么办?将五子棋游戏修改为围棋游戏,怎么办?2.1.3案例分析:日期统计程序问题:请问从2008年7月8日到2015年4月6日之间一共有多少天?思路:问题抽象算法分析计算从2008年到2015年之间整年包含的天数计算从2008年7月8日到当年年底(2008年12月31日)之间的天数计算从2015年元旦到2015年4月6日之间的天数面向对象的方法:创建一个CalculateDates类,将上述五个函数集成到该类当中利用.NET框架来实现:DateTimedd1,dd2;dd1=newDateTime(2015,4,6);dd2=newDateTime(2008,7,8);//两个日期对象相减,得到一个TimeSpan对象,Days是这一TimeSpan对象的属性intddays=(dd1-dd2).Days;Console.WriteLine(ddays);//结果2.1.4面向对象程序(OOP)的基本特性面向对象程序设计方法采用数据抽象与隐藏、层次结构体系、动态绑定等机制,提供一种模拟人类认知方式的软件建模方法,带来了系统的安全性、可扩充性、代码重用、易维护等人们期待的特性。面向对象程序包括四个基本特征:抽象、封装、继承与派生、多态性。抽象为了能够处理客观事物,必须对对象进行抽象。抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,忽略暂时不用部分细节。在OOP中,抽象就是找出对象的本质,抽出这一类对象的共有性质(数据和方法)并加以描述的过程。封装封装就是把对象的数据和方法结合成一个独立的单位,并尽可能隐蔽对象的内部细节。
把对象的全部数据和方法结合在一起,形成一个不可分割的独立单位(即对象)。信息隐蔽,尽可能隐蔽对象的内部细节,对外形成一个边界〔或者说形成一道屏障〕,只保留有限的对外接口使之与外部发生联系。继承与派生一个新类从已存在的类那里获得该类已有的特性叫作类的继承,已存在的类叫作父类,也叫作基类,产生的新类叫作子类或派生类。从一个已有的类那里产生一个新类的过程叫类的派生。已存在的类叫作父类,也叫作基类,产生的新类叫作派生类或子类。多态性多态性是指允许不同类的对象对同一消息作出不同的响应。多态是具有表现多种形态的能力的特征。在编程中使用多态的方法,可以在代码中本应使用某一具体子类的地方使用较为抽象的基类对象,这种方法所带来的好处是多态的代码具有“变色龙”的特性,即在不同的条件下,同样代码可以完成不同的功能。适当地在开发中应用多态特性,可以开发出可扩充性很强的系统。目录CONTENTS面向对象程序设计的基本概念类和对象属性和方法构造函数和析构函数12342.2类和对象2.2.1类和对象概述2.2.2类的定义2.2.3对象的创建和使用2.2.1类和对象概述什么是类?什么是对象?2.2.2类的定义2.2.3对象的创建和使用声明对象就是用类来定义对象变量。声明对象的格式为:类名对象名;为了使对象在内存中分配到保存数据的空间,在声明对象之后,常常需要使用关键字new对对象进行实例化,其方法为:对象名=new类名();对象的声明和实例化可以连起来完成,方法为:类名对象名=new类名();创建对象之后,它的成员可以通过运算符“.”来访问。myRectangle1.longside=0.0;RectanglemyRectangle1;myRectangle1=newRectangle();RectanglemyRectangle2=newRectangle();目录CONTENTS面向对象程序设计的基本概念类和对象属性和方法构造函数和析构函数12342.3属性和方法2.3.1方法的定义与调用2.3.2方法的参数类型2.3.3方法的重载2.3.4属性2.3.1方法的定义与调用放在一个类中的函数(通常附加一个存取权限修饰符如public和private)称为“方法(method)”。访问一个方法的最基本方式是通过类创建的对象。定义方法的一般形式为:其中访问修饰符包括存取修饰符,如private、protected和public,其他修饰符还包括new、static、virtual、sealed、overide、abstract等,除了static修饰符用于表示静态方法以外,其他修饰符都和继承机制有关。定义方法之后,则可以通过使用new关键字创建类的对象来访问此方法。2.3.2方法的参数类型C#方法的参数有五种类型:值参数、引用参数、对象类型参数、输出参数和参数数组。值参数:没有使用任何修饰符声明的值类型的参数。值参数在调用该参数所属的方法时创建,并用调用中给定的实参值初始化。当从该方法返回时值参数被销毁。对值参数的修改不会影响到原自变量。值参数通过复制原自变量的值来初始化。2.3.2方法的参数类型引用参数用ref修饰符声明的参数是调用者提供的自变量的别名,并不定义变量,而是直接引用原自变量对引用参数的修改就将直接影响相应自变量的值在方法调用中,引用参数必须被赋初值对象类型参数对象类型的参数传递的是地址,因此对参数的成员的修改将直接影响相应实参。在方法调用时,对象参数必须被赋初值2.3.2方法的参数类型输出参数用out修饰符定义的参数如果希望函数返回多个值,可使用输出参数。输出参数与引用参数类似,它并不定义自己的变量,而是直接引用原变量,这样当在函数内为输出参数赋值时,就相当于给原自变量赋值。与引用参数的差别在于:输出参数在调用方法前无需对变量进行初始化2.3.2方法的参数类型参数数组用params修饰符声明的变量称为参数数组允许向函数传递个数变化的参数在方法的参数类表中只允许出现一个参数数组,而且在方法同时具有固定参数和参数数组的情况下,参数数组必须放在整个参数列表的最后,同时参数数组只允许是一维数组。不能将params修饰符与ref和out修饰符组合起来使用。2.3.2方法的参数类型验证2.3.3方法的重载方法重载(overload)是指一个类有多个方法,名字相同,但方法的参数列表不一样,这里的不一样可能是个数或者类型不一样。重载和方法的返回值无关,返回值可以相同,也可以不同。重载的好处:对方法调用的程序员来说,它是友好的(程序员只关心自己调用的方法签名即可,不用管参数为NULL怎么办这些逻辑)。对于代码维护量来说,它是容易的(核心代码只放在参数签名最多的方法中)。对于代码扩展来说,它是直接的(只要修改核心方法代码即可,而不用一个方法一个方法的去COPY)。2.3.4属性属性是一种间接访问数据成员的机制,它不允许直接操作数据内容,而是通过访问器(也称为属性方法)访问数据成员。给属性赋值的时候使用set访问器,set访问器始终使用value设置属性值;获取属性值时使用get访问器,get访问器通过return返回属性值。属性的定义方式:只读属性、只写属性和读写属性属性和方法的区别和联系目录CONTENTS面向对象程序设计的基本概念类和对象属性和方法构造函数和析构函数12342.4构造函数和析构函数2.4.1构造函数2.4.2析构函数2.4.1构造函数有时候我们希望在创建对象的时候就直接给对象的数据赋初始值,利用类的构造函数就能完成这个任务。构造函数是一个与类名相同的函数,它的声明和普通方法类似,不同的是它没有返回值。构造函数也是可以重载的。构造函数是在对象创建的时候自动调用的。在创建对象的时候,根据参数的不同将调用不同的构造函数。构造函数主要用来为对象分配存储空间,完成初始化操作(如给类的成员赋值等)。2.4.1构造函数构造函数实例:1、定义2、调用:employeep=newemployee(100);System.Console.WriteLine("根据日薪的算法,员工的薪水等于:{0}",p.salary);employeef=newemployee(500,52);System.Console.WriteLine("根据员工周薪的算法,员工的薪水等与:{0}",f.salary);2.4.2析构函数析构函数(destructor)与构造函数相反,当对象脱离其作用域时,系统自动执行析构函数。析构函数往往用来做“清理善后”的工作。析构函数名也与类名相同,只是在函数名前面加一个波浪符~,例如~stud()。它不能带任何参数,也没有返回值(包括void类型)。只能有一个析构函数,不能重载。如果用户没有编写析构函数,编译系统会自动生成一个缺省的析构函数,它也不进行任何操作。所以许多简单的类中没有用显式的析构函数。C#采用了一种称为垃圾回收器的方法来自动管理内存,大部分内存释放工作在C#中基本上可以交给垃圾回收器去完成,而不需要写太多代码。尽管如此,在有些特殊情况下还是需要用到析构函数的,如在C#中释放非托管资源。思考1、 面向对象程序设计的基本思想和四大特征(习题2)2、 什么是类?什么是对象?举例说明。(习题1)3、 什么是属性?4、 什么是构造函数?有什么用?(习题4)5、 什么是封装?有什么好处?(习题3)第三讲
面向对象程序设计进阶目录CONTENTS命名空间和类库实例成员与类成员继承与多态委托与事件1234目录CONTENTS命名空间和类库实例成员与类成员继承与多态委托与事件12343.1命名空间与类库3.1.1命名空间3.1.2类库3.1.1命名空间在使用面向对象技术开发的现代软件系统中,经常拥有数百甚至上千个类,为了方便地管理这些类,面向对象技术引入了“命名空间(namespace)”的概念。命名空间只是一种逻辑上的划分,而不是物理上的存储分类。.NETFramework使用命名空间来管理所有的类。如果把类比喻成书的话,则命名空间类似于放书的书架,书放在书架上,类放在命名空间里。3.1.1命名空间例如:如果要使用在System命名空间中包含的Console类中定义的WriteLine方法,可以使用如下所示的代码行:System.Console.WriteLine("Hello,World!");需要在Console中包含的所有方法之前加System,这一做法很快便会令人厌倦,因此我可以将using指令插入到C#源文件的开头,这样在具体调用的时候就不用再指明命名空间了,如下所示:usingSystem;然后可以这样来调用:Console.WriteLine("Hello,World!");Using类似于C语言中的include3.2.1类库软件组件:可重用的软件模块在面向对象的.NET软件平台之上,软件组件的表现形式为程序集(Assembly),可以通过在VisualStudio中创建并编译一个类库项目得到一个程序集。类库项目编译之后,会生成一个动态链接库(DLL:DynamicLinkLibrary)文件。这就是可以被重用的.NET软件组件——程序集。默认情况下,类库文件名就是项目名加上“.dll”后缀。每个类库项目都拥有一个默认的命名空间,可以通过类库项目的属性窗口来指定。3.2.1类库“类库项目”、“程序集”和“命名空间”这三个概念的区别:每个类库项目编译之后,将会生成一个程序集。类库项目中可以拥有多个类,这些类可属于不同的命名空间。不同的类库项目可以定义相同的命名空间。“命名空间”是一个逻辑上的概念,它的物理载体是“程序集”,具体体现为“DLL”或EXE)文件。在VisualStudio中,可通过创建“类库”类型的项目生成程序集。一个程序集可以有多个命名空间,而一个命名空间也可以分布于多个程序集。一旦生成了一个程序集,在其他项目中就可以通过添加对这一程序集的引用而使用此程序集中的类。目录CONTENTS命名空间和类库实例成员与类成员继承与多态委托与事件12343.2实例成员与类成员3.2.1特性与访问规则3.2.2实例3.2.1特性与访问规则在类的成员类型或者返回值类型前面加上关键字static,就能将该成员定义为静态成员(staticmember)。常量或类型声明会隐式地声明为静态成员,其他没有用static修饰的成员都是实例成员(instancemember)或者称为非静态成员。静态成员属于类,被这个类的所有实例所共享;实例成员属于对象(类的实例),每一个对象都有实例成员的不同副本。静态方法在使用时不需要创建对象,而是通过类名直接调用。类的实例方法可以直接访问类的公有静态字段。3.2.1特性与访问规则3.2.1特性与访问规则程序的运行结果为:dynamicVar=1staticVar=1003.2.1特性与访问规则静态成员具有下列特征:静态成员必须通过类名使用.运算符来引用,而不能用对象来引用。一个静态字段只标识一个存储位置。无论创建了一个类的多少个实例,它的静态字段在内存中都只占同一块区域。静态函数成员(方法、属性、事件、运算符或构造函数)不能作用于具体的实例,在这类函数成员中不能直接使用实例成员,必须通过类名来引用。实例成员具有以下特点:实例成员必须通过对象名使用.运算符来引用,而不能用类名来引用。类的实例字段属于类的实例所有,每创建一个类的实例,都在内存中为实例字段开辟了一块区域。类的每个实例分别包含一组该类的所有实例字段的副本。实例函数成员(方法、属性、索引器、实例构造函数或析构函数)作用于类的给定实例,在它们的代码体内可以直接引用类的静态和实例成员。3.2.2实例3.2.1特性与访问规则技术要点:使用一个类变量lastAccountNumbr存储最后一个账户号,初始值设为0,逐渐累加。因为它是类变量,其实质上就是表示的系统当中的账户总数。定义一个私有的类方法NewUseraccountNum(),用于在内部产生新的账户号。账户号属性只有get访问器,没有set访问器,表明外界只能读取,不能设置,账户号由系统自动生成。目录CONTENTS命名空间和类库实例成员与类成员继承与多态委托与事件12343.3.2多态和派生3.3.1继承和派生3.3.2多态及其实现3.3.3实例3.3.1继承和派生回忆:什么是继承?举例说明。什么是派生?举例说明。派生类的声明格式思考:谁继承自谁?谁派生出谁?3.3.1继承与派生访问权限控制在C#的类当中,关键字this指类的实例自己,而关键字base则是指父类。关键字base的作用主要有两个:调用父类的构造函数和调用父类的方法。可访问性C#关键字含义公有public访问不受限制私有private只有类自身成员可以访问保护protected子类可以访问,其他类无法访问所有不必让外人知道的东西都是私有的。所有需要向外提供的服务都是公有的。所有的“祖传绝招”,“秘不外传”的都是保护的。3.3.2多态1——用虚函数virtual实现回忆:什么是多态?——一个接口、多种形态编程其实就是一个将具体世界进行抽象化的过程,多态就是抽象化的一种体现,把一系列具体事物的共同点抽象出来,再通过这个抽象的事物,与不同的具体事物进行对话。对不同类的对象发出相同的消息将会有不同的行为。多态的作用:应用程序不必为每一个派生类编写功能调用,只需要对抽象基类进行处理即可。大大提高程序的可复用性。派生类的功能可以被基类的方法或引用变量所调用,这叫向后兼容,可以提高可扩充性和可维护性。3.3.2多态1——用虚函数virtual实现Virtual——用于声明虚函数虚函数——必须是基类的非静态成员函数,可以在派生类中被重载。动态联编。3.3.2多态2——用抽象abstract实现被abstract修饰的方法默认是虚拟的,但是不能出现virtual关键词修饰被abstract修饰的类可以有已实现的成员,可以有自己的字段,可以有非abstract修饰的方法,但是不能实例化,因为抽象的东西是没有实例对应的。3.3.2多态2——用抽象abstract实现abstract和virtual的区别:
virtual关键字用于在基类中修饰方法。virtual的使用会有两种情况:情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法。那么在对派生类实例的调用中,该虚方法使用的是基类定义的方法。情况2:在基类中定义了virtual方法,然后在派生类中使用override重写该方法。那么在对派生类实例的调用中,该虚方法使用的是派生重写的方法。
abstract关键字只能用在抽象类中修饰方法,并且没有具体的实现。抽象方法的实现必须在派生类中使用override关键字来实现。3.3.2多态3——用接口interface实现关于接口:接口可由方法、属性、事件、索引器或这四种成员类型的任何组合构成。接口不能包含字段。接口成员默认是公共的,抽象的,虚拟的。若要实现接口成员,类中的对应成员必须是公共的、非静态的,并且与接口成员具有相同的名称和签名。思考:利用接口实现和之前一样的效果?3.3.2多态4——小结如果预计要创建组件的多个版本,则创建抽象类。抽象类提供简单易行的方法来控制组件版本。通过更新基类,所有继承类都随更改自动更新。另一方面,接口一旦创建就不能更改。如果需要接口的新版本,必须创建一个全新的接口。如果创建的功能将在大范围的全异对象间使用,则使用接口。抽象类应主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能。如果要设计小而简练的功能块,则使用接口。如果要设计大的功能单元,则使用抽象类。如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类。抽象类允许部分实现类,而接口不包含任何成员的实现。3.3.3实例请解释每一行输出结果:目录CONTENTS命名空间和类库实例成员与类成员继承与多态委托与事件12343.4委托与事件3.4.1回调函数3.4.2委托概述3.4.3委托举例3.4.4事件概述3.4.5综合案例3.4.1回调函数下面这些情况:你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。你去食堂打饭,你喜欢吃小炒热饭菜,所以你去了一个小炒窗口。你跟师傅说了要×××盖饭,师傅说:你是100号,喊到你的号你就来拿菜。然后你在旁边跟同学吹牛、或者看手机、或者干点你想干的任何事情。。。然后你听到师傅喊100号并且把菜放到窗口,你走到窗口,拿到你的菜。3.4.1回调函数下面这些情况:小明有一道数学题不懂,打电话给同学小军,小军听完题后感觉不能马上回答,解题得花些时间。这时候他们有几种选择:选择1,电话不挂(也可以挂了),小军解题,每过一会儿,小明就(打电话)问,怎么样了?问了十几分钟,小军才解答出来,告诉小明。选择2,电话挂了,小明把自己的电话告诉小军,小军做完后给小明打电话告诉小明答案。选择3,电话挂了,但小军不愿意花电话费给小明讲题,于是约定响铃三声,小明别接,然后再打回来。选择4,电话挂了,小军告诉小明自己的博客地址,解完了会写在博客上,小明做完其他作业后再去看。3.4.1回调函数分析:第一个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。第二个例子:对于老板:1、老板提供一个点餐的函数boss.Order(string菜名,double钱)2、老板有个做饭的函数,此函数耗时较长boss.Cook()3、老板提供一个事件,当boss.cook()执行完时,该事件被触发,boss.OnCookFinish;对于你:你需要有一个函数去订餐,也就是你的函数中需要执行类似于boss.Order(“红烧肉盖浇饭”,20),比如是me.Hungry()。你需要有一个函数作为回调函数去关注boss.OnCookFinish事件,这样当老板做好饭,你就可以知道是不是你的好了。3.4.1回调函数分析:第三个例子:第一种方法,小明在小军解题期间不能放下电话,只能不断询问。第二种方法,小明在小军解题期间可以做其他作业,当小军打电话来时,又得放下其他作业。第三种方法,小明可以做其他作业,当小军打电话来响铃时,就知道小军已经解完题了,可以马上,或在合适的时间去打电话给小军。第四种方法,小明可以先做完其他作业后去小明的博客看就行了。回调函数在什么场景有用?要在特定时候执行一个任务,至于是什么时候自己都不知道。比如某一时间到了或者某一事件发生或者某一中断触发。小明给小军留下电话号码,让他拨回来,就被称作回调(callback)。3.4.1回调函数回调函数有什么好处?程序变成异步了。也就是你不必再调用这个函数的时候一直等待这个时间的到达、事件的发生或中断的发生(万一一直不发生,你的程序会怎么样?)。再此期间你可以做做别的事情,或者四处逛逛。当回调函数被执行时,你的程序重新得到执行的机会,此时你可以继续做必要的事情了。回调函数有什么问题?学习成本会比普通函数高,需要有一定的抽象思维能力,需要对应用场景的理解。回调函数很多情况下会附带有跨线程操作甚至于跨进程的操作,处理起来比较复杂。3.4.1回调函数回调函数怎么起作用?把要执行的这个任务写成一个函数,将这个函数和某一事件建立关联。当这个关联完成的时候,这个函数从普通函数变身成为回调函数。回调函数什么时候执行?当该回调函数关心的那个事件触发的时候,回调函数将被执行。一般是触发这个事件的程序主体(通常是个函数或者对象)观察到有一个关注这个事件的回调函数的时候,这个主体负责调用这个回调函数。3.4.2委托概述委托是一种特殊的数据类型,它所定义的变量能接收的数值只能是一个函数。委托类型的变量可以接收一个函数的地址,很类似于C++语言的函数指针。委托是事件的基础。委托用于将方法作为参数传递给其他方法。事件处理程序就是通过委托调用的方法。用户可以创建一个自定义方法,当发生特定事件时某个类(例如Windows控件)就可以调用该方法。publicdelegateintPerformCalculation(intx,inty);3.4.3委托举例声明委托:publicdelegatevoidProcessBookDelegate(Bookbook);实例化委托:bookDB.ProcessPaperbackBooks(PrintTitle);bookDB.ProcessPaperbackBooks(totaller.AddBookToTotal);调用委托:processBook(b);
可以通过使用BeginInvoke和EndInvoke方法同步或异步调用委托。(详见教材8.3)3.4.4事件事件是对象发送的消息,以发信号通知操作的发生。事件可以由用户交互引起,例如单击按钮,也可能是由某些其他程序的逻辑引发,例如更改的属性值。引发事件的对象称为eventsender,事件发送方不知道哪个对象或方法将接收到(处理)它引发的事件。可以使用C#中的event关键字在事件类中签名并指定事件的委托来定义一个事件。3.4.5实例思考1、2、3、4、5、第四讲
基于C#的数据结构及实现数据结构基础1数组及其C#实现2队列及其C#实现3堆栈及其C#实现4查找5排序6Contents目录数据结构基础1数组及其C#实现2队列及其C#实现3堆栈及其C#实现4查找5排序6Contents目录4.1数据结构基础4.1.1数据结构4.1.2算法4.1.3用C#设计数据结构项目的基本方法4.1.1数据结构什么是数据结构讨论计算机系统中数据的组织形式及相互关系。基本概念数据:广泛的含义,包括各种数值、字母、字符、图形图像、语言、程序等。即所有能输入到计算机中,并能被计算机所处理的符号的总称。对客观事物采用计算机进行识别、存储和加工所进行的描述。数据元素:数据的基本单位,数据元素的类型为基本类型或构造类型。数据项:数据的最小单位。4.1.1数据结构结构:数据元素之间的相互关系,体现为一些运算。一种逻辑结构。物理结构:存储结构。数据在计算机中的存储。操作:数据的处理与运算。数据结构研究的主要内容数据元素之间的逻辑关系采用的存储结构对这些数据元素采用何种方式进行操作4.1.1数据结构数据结构的三个层次数据的逻辑结构数据的存储结构数据的操作集合数据的逻辑结构1)线性结构:有且仅有一个开始数据元素;有且仅有一个终点数据元素;中间所有数据元素有且仅有一个直接前趋和一个直接后继。2)非线性结构:每个数据元素可能有多个直接前趋和多个直接后继。4.1.1数据结构数据的存储结构:即数据的物理结构,是数据的逻辑结构在存储器里的实现。1)顺序存储:用物理存储单元的邻接关系来表示数据元素之间的逻辑关系。
2)链式存储:用指针来表示元素之间的逻辑关系。
3)索引存储:建立索引表。
4)散列存储:根据元素的关键字(唯一标识该元素),直接计算出元素的存储地址。数据结构上的操作(数据的运算): 遍历、插入、更新、删除、查找、排序4.1.1数据结构数据的逻辑结构、物理结构及操作之间的关系:
1)同一逻辑结构,不同物理结构,得到不同的数据结构。
2)同一逻辑结构,同一物理结构,定义不同的运算集合,得到不同的数据结构。
3)对同一逻辑结构的同一操作,只要物理结构不同,其实现的方法也就不同。数据的逻辑结构、物理结构及数据的运算是紧密联系的一个整体4.1.2算法算法是对特定问题求解步骤的一种描述,它是指令的有限序列。算法通常包含两部分:进行的操作或运算;涉及的操作对象(数据)算法具有五个重要特性:有穷性、确定性、可行性、有输入、有输出。算法分析算法设计的目标:正确性、可使用性、可读性、健壮性、高效率与低存储量需求。算法时间效率分析(复杂度)算法存储空间分析4.1.3用C#设计数据结构项目求解数据结构问题的一般步骤建立求解问题的模型存储结构设计系统设计编程项目运行并评估应用程序项目的基本结构如图C#中通常将数据存放为类的字段,再通过相关方法对其进行操作数据结构基础1数组及其C#实现2队列及其C#实现3堆栈及其C#实现4查找5排序6Contents目录4.2数组及其C#实现4.2.1线性结构4.2.2数组4.2.2数组的C#实现4.2.1线性结构线性结构是指数据的逻辑结构,反映数据元素之间的逻辑关系。基本特点:数据元素有序且有限
①有且仅有一个起始元素
②有且仅有一个终点元素
③其余为内部元素线性数据结构类型:线性表、栈、队列、数组、串4.2.1线性结构线性表:n个数据元素的有限序列;元素与元素之间的关系为线性;同一表中所有数据元素类型相同。表示:(a1,a2,……ai,……an-1,an)线性表的逻辑结构:线性线性表的物理结构:
顺序存储顺序表
链式存储线性链表操作:初始化;求表长;取元素;定位;插入;删除4.2.2数组物理结构为顺序存储的线性表叫做顺序表,在C#(其他大部分语言也一样)中通常用数组来表示。线性链表:非连续存储。用一组任意的存储单元存储线性表的数据元素。每个数据节点包括数据本身和表示节点前后关系的指针。4.2.3数组(C#表示)数组的声明:int[]myIntArray;注:声明数组时,方括号([])必须跟在类型后面,而不是变量名后面。在C#中,将方括号放在变量名后是不合法的语法。数组的初始化:myIntArray=newint[3];myIntArray=newint[]{1,2,3};int[]myIntArray={1,2,3};//当使用这种方法对数组进行初始化时,只能在声明变量数组时使用,不能在声明数组之后使用。数组的访问:数组在声明和初始化后,可以使用索引器进行访问,索引器总是以0开头,表示第一个元素。4.2.3数组(C#表示)思考:如何对数组进行运算?(初始化;求表长;取元素;定位;插入;删除)算法如何实现?数据在存储单元中的位置怎么变化?初始化的方法求表长的方法取元素的方法:直接用索引器(下标即可访问)查找定位?插入和删除?插入:在表中第i个位置上插入新元素new_elem
插入新元素a1,a2,…,ai-1,new_elem,ai,ai+1,…,ana1,a2,…,ai-1,ai,ai+1,…,ana1a2……ai-1aiai+1……anana1a2……ai-1……an-1ai删除:删除表中第i个数据元素 a1,a2,…,ai-1,ai,ai+1,…,an删除第i个元素a1,a2,…,ai-1,ai+1,…,ana1a2……ai-1aiai+1……anan…ai+1ai+2a1a2……ai-1
4.2.3数组(C#表示)数组、ArrayList和List数组在内存中是连续存储的,所以它的索引速度非常快,而且赋值与修改元素也很简单,但是要插入或删除数据比较麻烦,而且在声明数组的时候必须指定数组的长度。ArrayList是命名空间System.Collections下的一部分,在使用该类时必须进行引用,同时继承了IList接口,提供了数据存储和检索。ArrayList对象的大小是按照其中存储的数据来动态扩充与收缩的。所以,在声明ArrayList对象时并不需要指定它的长度。ArrayList会把所有插入其中的数据当作为object类型来处理,在我们使用ArrayList处理数据时,很可能会报类型不匹配的错误,因此ArrayList不是类型安全的。List类是ArrayList类的泛型等效类,它的大部分用法都与ArrayList相似。最关键的区别在于,在声明List集合时,我们同时需要为其声明List集合内数据的对象类型。List<string>list=newList<string>();list.Add(“abc”);//新增数据list[0]=“def”;//修改数据list.RemoveAt(0);//移除数据在适用的情况下,推荐使用List代替常规数组数据结构基础1数组及其C#实现2队列及其C#实现3堆栈及其C#实现4查找5排序6Contents目录4.3队列及其C#实现栈与队列是两种特殊的线性表,它们的逻辑结构都是线性的,他们的操作运算都限制在表的端点进行。队列:是一种操作受限的线性表,只允许在队头删除,在队尾插入。队列的访问规则:先进先出FIFO——FirstinFirstout队头front队尾reara1a2a3……an出队dequeue入队enqueue4.3队列及其C#实现.NET中(以C#为例)提供了Queue类实现队列。此类将队列作为循环数组实现。存储在Queue中的对象在一端插入,从另一端移除。Queue的容量是Queue可以保存的元素数。Queue的默认初始容量为32。向Queue添加元素时,将通过重新分配来根据需要自动增大容量。Queue接受空引用(在VisualBasic中为Nothing)作为有效值并且允许重复的元素。Queue类的成员数据结构基础1数组及其C#实现2队列及其C#实现3堆栈及其C#实现4查找5排序6Contents目录4.4堆栈及其C#实现堆和栈严格来说是不同的,但从数据结构的角度,可以一起研究。堆栈是运算受限的线性表,仅在表的一端进行插入或删除操作。4.4堆栈及其C#实现.NET中(以C#为例)提供了Stack类实现堆栈。Stack<T>作为数组来实现。参考https:///zh-cn/library/3278tedw(v=vs.110).aspxStack<T>的容量是指Stack<T>可以容纳的元素数。向Stack<T>添加元素时,将通过重新分配内部数组,根据需要自动增大容量。可通过调用TrimExcess来减少容量。如果Count小于堆栈的容量,则Push的运算复杂度是O(1)。如果需要增加容量以容纳新元素,则Push的运算复杂度成为O(n),其中n为Count。Pop的运算复杂度为O(1)。Stack<T>接受null作为引用类型的有效值并且允许有重复的元素。数据结构基础1数组及其C#实现2队列及其C#实现3堆栈及其C#实现4查找5排序6Contents目录4.5查找方法及其C#实现4.5.1基本原理4.5.2C#实现4.5.1查找方法的基本原理关键字:元素的标志,唯一标识一个数据元素查找:从大量的数据中查找所需的数据,查找一个关键字等于给定值的数据元素,即按关键字查找。查找表:待查数据元素的集合查找方法:顺序查找、折半查找、分块查找、查找效率:与查找表中数据元素的组织形式及使用的查找方法密切相关。4.5.1查找方法的基本原理顺序查找:从第一个数据元素开始查找,直到查找成功或失败。查找效率不高,仅适用于短表折半查找:先确定待查记录所在的范围,逐步缩小范围直到查找成功或失败,前提是待查找的表是有序表。适用场合:顺序存储结构的有序查找表; 链式存储结构的二叉排序树; 不适合单链表其他方法:分块查找、树表查找、哈希查找4.5.2C#中的实现List<T>:Contains(T) :确定某元素是否在List<T>中。Exists(Predicate<T>):确定List<T>是否包含与指定谓词定义的条件匹配的元素。Find(Predicate<T>) :搜索与指定谓词所定义的条件相匹配的元素,并返回整个List<T>中的第一个匹配元素。FindAll(Predicate<T>):检索与指定谓词定义的条件匹配的所有元素。其他:FindIndex(Int32,Int32,Predicate<T>);FindIndex(Int32,Predicate<T>);FindIndex(Predicate<T>);FindLast(Predicate<T>);FindLastIndex(Int32,Int32,Predicate<T>);FindLastIndex(Int32,Predicate<T>);FindLastIndex(Predicate<T>);IndexOf(T)…………4.5.2C#中的实现Queue<T>:Contains(T) :确定某元素是否在Queue<T>中。Equals:已重载。确定两个Object实例是否相等。(从Object继承)其他参考:https:///zh-cn/library/system.collections.queue_members(v=vs.80).aspxStack<T>:Contains:确定某元素是否在Stack<T>中。First<T>():返回序列中的第一个元素。Last<T>():返回序列的最后一个元素。其他参考:
https:///zh-cn/library/3278tedw(v=vs.100).aspx数据结构基础1数组及其C#实现2队列及其C#实现3堆栈及其C#实现4查找5排序6Contents目录4.6排序4.6.1基本原理4.6.2C#实现方法4.6.1基本原理排序:又称分类,是将一组元素按照它们的排序码大小进行递增或递减排列的运算。排序码: 排序的依据,不一定是关键字,是元素中的一个或多个字段,不同元素排序码可以相同。排序算法的稳定性: 对具有相同排序码的元素排序后,元素的相对位置保持不变,是稳定的。否则,不稳定。内部排序:整个排序过程在计算机内存中进行,算法开销主要在开销在元素的比较和移动上。外部排序:既使用内存,同时又使用外存的排序,开销不仅在元素的比较和移动上,更多的开销在对外存的访问上。4.6.1基本原理直接插入排序法:基本思想:从原表中取一个元素插入到已排好序的表中,得到一个新的、元素个数增1的有序表。算法分析:将原表分为已排序表和未排序表:已排序表:[R1R2……Ri-1] 未排序表:[RiRi+1……Rn]每次从未排序表中取出表头元素按排序关系插入到排序表中。当未排序表为空时,排序结束插入运算为从后向前比较先取Ri与Ri-1比较,若Ri<Ri-1,则Ri-1后移一个位置,再取下一个元素Ri-2与Ri比较,依此类推,直到找到插入位置,就在该位置插入元素。需进行(n-1)趟插入排序简单,容易实现,适于待排元素n很少的情况。但每次比较可能搬移多个元素。是稳定的算法。4.6.1基本原理简单选择排序法:基本思想:从无序表中依次选取排序码最小的元素,插入到有序表的表尾。算法分析:直接在原表进行操作先在无序表中找到最小元素最小元素与无序表表首元素交换位置原无序表:[i,……,n]新有序表:[1,……,i-1]4.6.1基本原理冒泡排序法:基本思想:从表首元素开始,两两比较,若x[i].key>x[i+1].key,则两个元素交换。经过一趟冒泡排序后,具有最大排序码的数据元素就移到了最后。再对前n-1个数据元素冒泡排序,依此类推,直到在一趟冒泡排序过程中没有进行过交换元素的操作,整个排序过程结束。算法效率:在一趟冒泡排序中同时完成了较大元素的上冒和较小元素的下沉,效率较高。稳定的。4.6.1基本原理快速排序法:基本思想:从待排序的n个数据元素中任意选出一个数据元素x[i]作为基准元素。调整该序列中各个数据元素的位置,使得x[i]之前的数据元素的排序码都小于x[i]的排序码,x[i]之后的数据元素的排序码都大于x[i]的排序码,从而确定了x[i]在该序列中的位置。此时,该序列被分割成2个独立的部分。再对这2个部分分别进行快速排序,最后达到整个序列有序(子序列长度为1)。算法效率:若基准元素关键字为最大(或最小),退化成冒泡排序,效率不高;若基准元素关键字为中间值,则效率高(排序趟数少,每一趟中交换的元素少)可用栈消去递归(不支持递归的系统无法实现递归运算)表的规模越大越能体现快速性不稳定4.6.1基本原理归并排序法:基本思想:(merging)将两个或两个以上的有序表合并成一个新的有序表。主要用于将两个有序的字表合并成一个新的有序表。算法分析:将一个长度为n的待排序列,看成n个长度为1的有序序列将相邻的两个子序列两两归并,产生n/2个长度为2或1的有序序列对这n/2个有序序列两两归并,依此类推,直到得到一个长度为n的有序序列。算法效率基本同快速排序,但需辅助数组,占用较多存储空间稳定4.6.2C#实现可以用C#的语法,C语言的风格自己实现上述所有排序算法。.NET中部分类型也提供了相应的方法,这些方法在不同的情况下会选用不同的排序算法。以List<T>为例:Reverse() :将整个List<T>中元素的顺序反转。Reverse(Int32,Int32) :将在指定下标范围内的元素顺序反转.Sort() :使用默认的比较器对所有数据元素进行排序.Sort(Comparison<T>):使用指定的比较代理方法对整个List<T>中的元素进行排序Sort(IComparer<T>) :使用指定的比较器对整个List<T>中的元素进行排序。Sort(Int32,Int32,IComparer<T>):使用指定的比较器对List<T>中某个范围内的元素进行排序。参考学习:/think_soft/article/details/3446393第五讲
面向对象入门——计算器设计提出问题1控制台实现的计算器程序2简单的Windows计算器程序3Contents目录提出问题1控制台实现的计算器程序2简单的Windows计算器程序3Contents目录5.1要解决的问题一道面试题:“请用C++、Java、C#或VB.NET任意一种面向对象语言实现一个计算器控制台程序,要求输入两个数和运算符号,得到结果。”下面分别用控制台和WindowsForm来实现。提出问题1控制台实现的计算器程序2简单的Windows计算器程序3Contents目录5.2控制台实现及扩展技术要点: 要求用C#语言实现。 要求实现的是控制台程序。 要求的程序输入参数包括操作数1、操作数2和运算符号共三个。 要求的程序输出为最终的计算结果,直接在控制台界面显示即可。5.2控制台实现及扩展classProgram{staticvoidMain(string[]args){Console.Write("请输入数字A:");stringA=Console.ReadLine();Console.Write("请选择运算符号(+、-、*、/):");stringB=Console.ReadLine();Console.Write("请输入数字B:");stringC=Console.ReadLine();stringD="";5.2控制台实现及扩展if(B=="+")
D=Convert.ToString(Convert.ToDouble(A)+Convert.ToDouble(C));if(B=="-")D=Convert.ToString(Convert.ToDouble(A)-Convert.ToDouble(C));if(B=="*")D=Convert.ToString(Convert.ToDouble(A)*Convert.ToDouble(C));if(B=="/")D=Convert.ToString(Convert.ToDouble(A)/Convert.ToDouble(C));Console.WriteLine("结果是:"+D);}}5.2控制台实现及扩展思考:上述程序当中的变量A、C、D的最大值分别是多少?如果超过最大值了会怎样?如果选择的运算符为除,第二个操作数输入为0,会产生什么样的结果?如何解决?上述程序是否完全符合题目要求?不足之处:变量命名,现在的命名就是A、B、C、D,变量不带有任何具体含义,这是非常不规范的。判断分支,上述写法,意味着每个条件都要做判断,等于计算机做了三次无用功。数据输入有效性判断等,如果用户输入的是字符符号而不是数字怎么办?如果除数时,客户输入了0怎么办?5.2控制台实现及扩展改进:将变量名从无意义的A、B、C、D,变成了更加规范的命名方式。用switch替换了if判断。增加了对除数为0的情况的判断和处理。加上了程序的异常处理。C#当中程序的异常处理通常使用try……catch或者try……finally……catch来完成。小结:程序基本能满足题目的要求,且考虑了一些异常输入的情况。但总体而言,并没有体现任何面向对象的思想,代码没有任何可以封装和重用的部分。提出问题1控制台实现的计算器程序2简单的Windows计算器程序3Contents目录5.3简单的Windows计算器程序简单程序中的面向对象思想上述代码可否重用?面向对象三大特性是封装、继承和多态。如何在简单的计算器程序中体现这三大特性?5.3简单的Windows计算器程序界面搭建步骤略部分实现思路分析:为了让业务逻辑与界面逻辑分开,让其的耦合度下降,单独建立一个负责操作执行的逻辑类CalculateOperation,使其完成基本的数据运算操作。该类主要包含计算结果这一个函数,其实现方式可以同前例。5.3简单的Windows计算器程序部分实现思路分析:定义全局变量进行数据的保存。分别实现每个数字按钮的响应事件。按键0到按键9的功能非常相似,只是具体的某一个内容不太一样,因此我们可以用一个共同的函数来处理逻辑,将不同的内容作为参数传入即可。5.3简单的Windows计算器程序部分实现思路分析:对于数字0到9的按键响应函数,实际上都是在直接调用函数ZeroRemove,只是传入的参数不一样而已。如果发现输入响应操作处理的有问题,则只需要修改函数ZeroRemove即可,而不需要依次修改0到9的响应函数了,这种设计充分体现了公共函数的优越性。对于加减乘除这类操作按钮来说,也可以设计一个共同的处理函数。因为在按下这一类按钮之后,程序需要做的处理动作几乎是一致的,不同的仅仅是记录的数据。(函数SuppliedOperator)在设计了操作处理函数之后,相应的加减乘除的按钮响应函数也可以很简单的实现了。补充完善其他一些按钮事件响应函数(等号、小数点、删除等)。5.3简单
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 软件架构容器化部署自动化实践
- 先天性小儿麻痹症护理中的紧急情况处理
- 休克早期识别的护理评估工具
- 儿科呼吸系统疾病护理
- 妇产科腹部手术后预防伤口积液护理
- PDCA方法提升血透室护理服务效率
- 服务器安全实验课程设计
- 奥克斯空调课程设计
- 圆弧钢板施工方案(3篇)
- 烘焙年节活动策划方案(3篇)
- GB/T 44143-2024科技人才评价规范
- 房屋续租再签合同范本
- 矿山生态修复施工组织设计
- 初一上册七年级英语单项选择(50题)含答案
- 麻醉复苏室规章制度-课件
- 南华大学《C 语言程序设计》作业题
- 2015-2022年江苏农林职业技术学院高职单招语文/数学/英语笔试参考题库含答案解析
- 议论文阅读训练10篇(附答案及解析)
- 插画大师及作品分课件
- 上海师范大学C语言期末考试标准试卷
- 输血技术(师)考试历年真题及答案完整版
评论
0/150
提交评论