c 面向对象的高级编程PPT课件_第1页
c 面向对象的高级编程PPT课件_第2页
c 面向对象的高级编程PPT课件_第3页
c 面向对象的高级编程PPT课件_第4页
c 面向对象的高级编程PPT课件_第5页
已阅读5页,还剩48页未读 继续免费阅读

下载本文档

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

文档简介

1、 本章教学目的介绍面向对象高级编程的相关知识,使学生对C#高级编程有一个感性认识。 本章教学要求(1)掌握继承、泛型的概念及基本用法;(2)掌握与实验有关的相关内容,包括封装、继承与多态、泛型处理 ;(3)了解其他内容。第1页/共53页实验中的问题解答1. 如何添加某个事件(例如窗体的Shown事件)?如何删除某个事件?答:添加和删除事件均在设计视图下利用属性中的事件完成。2. 使用textBoxStartAmount.Focus(); 与使用键让某控件获取焦点有何不同?答:前者用于动态设置,后者用于静态设置。3. 实验2:private double Caculate(double star

2、tAmount, double rate, int count)叠加次数count是什么意思?答:叠加次数是指到期后将计算出来的利息作为存款再次计算,例如存款时间为1年,则按年算息叠加次数为1,按月算息叠加次数为12,按季度算息叠加次数为4。4. 实验报告什么时候交?进度如何安排?答:各人根据自己的情况安排进度,完成一个,写一个实验报告。5. 如何定义属性?如何给属性赋值?如何获取属性的值?答:见书上P59例3-10第2页/共53页4.1 封装、继承与多态封装:隐藏调用者不需要了解的信息。继承:简化类的设计。多态:类为名称相同的方法提供不同实现方式的能力。第3页/共53页封装 模块信息通过类封

3、装 类的成员通过字段、属性、方法、事件封装u私有的用privateu可以被继承的用protectedu公共成员用publicu不要为了方便把什么都定义成publicu不要为了方便把什么都定义成static 通过属性进行封装的例子:P73例4-1第4页/共53页封装举例:对象封装了对象的数据以及对这些数据的操作。对象是属性和操作的组合对象的表现(服务、接口)和实现细节分开第5页/共53页/MyClass.csusing System;namespace ConsoleTest class MyClass private int number; public int Number get retu

4、rn number; set if (value 0) number = value; /Program.cs/Program.csusing System;using System;namespace ConsoleTestnamespace ConsoleTest public class Program public class Program public static void Main() public static void Main() MyClass me = new MyClass me = new MyClass();MyClass(); me.Number = -1;

5、me.Number = -1; Console.WriteLine(Console.WriteLine( Number:0, Number:0, me.Number);me.Number); Console.ReadLine(); Console.ReadLine(); 回答:回答:NumberNumber输出的值是多少?输出的值是多少?第6页/共53页练习(1) Question 47. (单选)In Object oriented Programming, how would you describe encapsulation?1. The conversion of one type

6、of object to another.2. The runtime resolution of method calls.3. The exposition of data.4. The separation of interface and implementation. 答案:4第7页/共53页继承 继承表示现实世界中遗传关系的直接模拟。 它表示类之间的内在联系以及对属性和操作的共享。第8页/共53页继承(续)声明扩充类的语法: 访问修饰符 class 扩充类名称:基类名称 /程序代码 扩充类继承了所有定义在基类中数据的定义和方法。但是扩充类不继承基类的构造函数。继承的例子(1):P7

7、6例4-2两种实现继承的方式:类继承和接口继承。类继承只允许单一继承 ,接口可实现多重继承。被继承的类叫基类继承自其他类的类叫扩充类第9页/共53页多态 用相同的操作名在一个类层次的不同类中实现不同的功能,相同的消息由同一(父)类的不同对象接收时,导致不同的行为。 举例:几何图形类层次中的多态性。其派生类“圆”、“长方形”、“三角形”等都有方法“求面积”。几何图形圆三角形几何图形圆Shape类 GetArea() Rectangle类GetArea()Circle类GetArea()Triangle类GetArea()第10页/共53页1、虚拟方法 在基类中,如果想让某个方法或者事件被扩充类重

8、写,可以使用修饰符virtual表明: public virtual void myMethod() /程序代码 扩充类则用override重写: public override void myMethod() /程序代码 多态(续)第11页/共53页/MyClass.csusing System;namespace ConsoleTest class MyClass public virtual void Hello() Console.WriteLine(123); /MyNewClass.cs/MyNewClass.csusing System;using System;namespac

9、e ConsoleTestnamespace ConsoleTest class MyNewClass : MyClass class MyNewClass : MyClass private string str = private string str = hello;hello; public override void Hello() public override void Hello() Number = 2; Number = 2; Console.WriteLine(str);Console.WriteLine(str); 第12页/共53页多态(续) 使用虚拟方法和重写方法时

10、,要注意下面几个方面: 虚拟方法不能声明为静态的。 Virtual不能和private一起使用。 重写方法的名称、参数个数、类型以及返回值都必须和虚拟方法的一致。 举例 P79页例4-4第13页/共53页多态(续)2、隐藏基类的方法 在扩充类中,可以使用new关键字来隐藏基类的方法,即使用一个完全不同的方法取代旧的方法。 与方法重写不同的是,使用new关键字时并不要求基类中的方法声明为virtual,只要在扩充类的方法前声明为new,就可以隐藏基类的方法。第14页/共53页多态(续)3、抽象类 使用abstract修饰符。 抽象类只能做基类。 抽象类与非抽象类的区别: 第一是抽象类不能直接被实

11、例化,只能在扩充类中通过继承使用,对抽象类使用new运算符会产生编译时错误 第二个不同点是抽象类可以包含抽象成员,而非抽象类不能包含抽象成员。当从抽象类派生非抽象类时,这些非抽象类必须具体实现所继承的所有抽象成员。第15页/共53页补充题目 Question 32. (单选)以下描述错误的是()1.在C+中支持抽象类而在C#中不支持抽象类。2.C+中可在头文件中声明类的成员而在CPP文件中定义类的成员,在C#中没有头文件并且在同一处声明和定义类的成员。3.在C#中可使用 new 修饰符显式隐藏从基类继承的成员。4.在C#中要在派生类中重新定义基类的虚函数必须在前面加Override。 第16页

12、/共53页练习(2)abstract class BaseClass public virtual void MethodA() Console.WriteLine(BaseClass);class Class1: BaseClass public void MethodA() Console.WriteLine(Class1);class Class2: Class1 在Main方法中执行下列语句: Class2 o = new Class2(); o.MethodA(); 问:执行结果是什么? 第17页/共53页4.2 版本控制 用C#编写方法时,如果在扩充类中重写基类的方法,需要用ove

13、rride声明;要隐藏基类的方法,需要用new声明,这就是C#进行版本控制的依据。 调用非虚拟方法时不会受到版本的影响 调用虚拟方法的实现部分可能会因扩充类的重写而影响执行结果。举例: P83 例4-8 P84 例4-9 第18页/共53页4.2 版本控制(续)调用原则:调用继承的最后实现部分的方法 P85 例4-10C#允许派生类包含与基类方法名称相同的方法,规则如下:1) 基类方法必须声明为virtual2)若派生类中方法前无new或override关键字,方法执行按存在new关键字一样执行3)若派生类中方法前带new关键字,则此方法被定义为独立于基类的方法4)若派生类中方法前带overr

14、ide关键字,则派生类调用此方法,而非基类的方法。5)可从派生类中使用base关键字调用基类方法。 第19页/共53页补充知识:C#面试题public class A public A() Console.WriteLine(“A”); public virtual void Fun() Console.WriteLine(A.Fun(); public class B: A public class B: A public B() public B() Console.WriteLine( Console.WriteLine(“B B”); ); public new void Fun()

15、public new void Fun() Console.WriteLine(B.Fun(); Console.WriteLine(B.Fun(); public static void Main() public static void Main() A a = new B(); A a = new B(); a.Fun(); a.Fun(); /输出结果为:输出结果为: A A B B A.Fun A.Fun()()第20页/共53页4.3 接口 接口的主要特点是只有声明部分,没有实现部分。 接口成员的实现是通过类完成的。 定义在接口中的方法都是public的。 使用interface关

16、键字声明一个接口。常用的语法是: 访问修饰符 interface 接口名称 / 接口体 一般情况下,以大写的“I”开头指定接口名,表明这是一个接口。 需要在不相关的类中实现同样的功能时,可以使用接口。第21页/共53页4.3 接口 P88 例4-11 显示方式实现接口 例4-12 注意:显示实现接口时,不能通过类的实例进行访问,而必须使用接口实例。 通过接口实现多继承 例4-13第22页/共53页补充知识:C#面试题不定项选择题(1) 以下叙述正确的是: A. 接口中可以有虚方法。 B. 一个类可以实现多个接口。 C. 接口不能被实例化。 D. 接口中可以包含已实现的方法。 B、C(2)以下叙

17、述正确的是: A. 接口和抽象类一样均只能声明,而不能有实现部分。 B. 类可以继承多个接口,但仅能从一个抽象类或其它类型的单个类继承。 C. 接口中可以定义属性、方法和事件,但只声明不实现。 D. 类的多继承可以通过接口实现。 B、C、D第23页/共53页4.4 委托 类似与C+中的函数指针,但有很大不同 委托的声明 例如: public delegate void FuncDelegate(string str); 委托的使用 具体内容不再详细讲述第24页/共53页4.5 序列化与反序列化 序列化 获取对象并将其状态信息转换为可存储或可传输形式的过程。 反序列化 将对象还原回序列化之前的内

18、容。 序列化和反序列化是一个互逆的过程。 .NET Framework提供的两种序列化技术 二进制序列化 XML和SOAP序列化第25页/共53页4.5 序列化与反序列化1、如何序列化一个类:在类的上方加上Serializable特性即可。 Serializable public class MyClass 2、二进制序列化 MyClass user = new MyClass(); IFormatter formater = new BinaryFormatter(); Stream stream = new FileStream(UserInfo.bin, FileMode.Create,

19、 FileAccess.Write, FileShare.None); formater.Serialize(stream, user); stream.Close(); 特点: 二进制序列化会将一个类的所有成员变量都进行序列化,包括私有变量、公共属性、方法等。 第26页/共53页4.5 序列化与反序列化3、二进制反序列化 IFormatter formatter = new BinaryFormatter(); Stream stream = new FileStream(UserInfo.bin, FileMode.Open, FileAccess.Read, FileShare.Read

20、); MyClass c = (MyClass)formatter.Deserialize(stream); stream.Close();特点:反序列化后,对象c与序列化之前的状态完全相同。第27页/共53页补充:二进制序列化与反序列化举例保存窗体位置、颜色与数据库连接信息设置第28页/共53页补充:二进制序列化与反序列化举例 当输入服务器等信息、改变窗体前景色、位置后,退出应用程序,再次启动,可看到仍然是退出前的状态。第29页/共53页4.5 序列化与反序列化4、XML序列化(1)XML 序列化仅将对象的公共字段和属性值序列化为XML流,而不转换方法、索引器、私有字段或只读属性(只读集合除

21、外)。 (2)XML 序列化不包括类型信息,即不能保证序列化后的对象在被反序列化时,变为同一类型的对象。 (3)XML序列化的实现步骤Class1 user = new Class1();user.AccountName = aa;XmlSerializer mySerializer = new XmlSerializer(typeof(Class1);StreamWriter myWriter = new StreamWriter(UserInfo.xml);mySerializer.Serialize(myWriter, user);myWriter.Close();第30页/共53页4.

22、5 序列化与反序列化(4)XML反序列化的步骤Class1 c;XmlSerializer mySerializer = new XmlSerializer(typeof(Class1);FileStream myFileStream = new FileStream(UserInfo.xml, FileMode.Open);c = (Class1) mySerializer.Deserialize(myFileStream);myFileStream.Close();注意:反序列化一个对象时不会调用构造函数,这一点与创建对象不同。第31页/共53页4.6 泛型处理 泛型(Generic)一般

23、用在集合和在集合上运行的方法中。.NET框架2.0以前的版本不支持泛型。 使用泛型具有以下明显的优点: 1)可以避免以下两个问题:内部实现代码冗余和困扰开发人员的含混不清的编译器错误提示; 2)类型安全;3)二进制代码重用;4)性能;5)清晰性。 第32页/共53页4.6 泛型问题描述public class Stack object m_Items; public void Push(object item) . public object Pop() . 使用举例:Stack stack = new Stack();stack.Push(1);int number=(int)stack.P

24、op();stack.Push(“str”);string str=(string)stack.Pop();第33页/共53页基于Object的堆栈缺点 性能问题 值类型需频繁地装箱、拆箱,造成较多的垃圾碎片,增加垃圾回收的负担 引用类型需要强制类型转换 类型安全问题(更严重) 编译时任务类型都转换成object,无法保证运行时类型安全。 例如:Stack stack = new Stack(); stack.Push(“abc”); int number = (int)stack.Pop();第34页/共53页4.6 泛型解决办法public class IntStack int m_Ite

25、ms;public void Push(int item) .public int Pop() . public class StringStack public class StringStack string m_Items;string m_Items;public void Push(string item) public void Push(string item) .public string Pop() public string Pop() . . 功能相似,代码冗余!维护麻烦!第35页/共53页基于Object的堆栈IntStackStringStack代码冗余,维护复杂,工

26、作效率低性能问题、类型安全问题有没有好的解决办法?有,泛型第36页/共53页解决方法采用泛型public class Stack T m_Items;public void Push(T item) .public T Pop() . 第37页/共53页泛型是如何实现的? 在.NET 2.0中,泛型在IL(中间语言)和CLR本身中具有本机支持 编译泛型时,就像编译类一样,泛型仅保留一个占位符。 而用特定类型实例化的泛型代码,编译时会将泛型替换为实例化的特定类型。第38页/共53页泛型实现 public class Stack T m_Items; public void Push(T item

27、) . public T Pop() . 使用举例:Stack stack = new Stackstack.Push(1);int number = stack.Pop();第39页/共53页泛型的定义和引用 泛型定义代码语法如下: 访问修饰符返回类型 泛型支持类型 泛型名称 其中CLR支持的泛型类、结构、方法、接口和委托等。泛型类定义举例:class Node T data; Node next; 例4-19 引用泛型类第40页/共53页泛型的引用泛型类定义举例: void Swap(ref T item1, ref T item2) T temp = item1; item1 = ite

28、m2; item2 = temp; 例4-20 引用一个泛型方法程序举例:使用泛型方法来实现int、double、float类型的数据交换方法。第41页/共53页常用泛型 凡是有对应泛型类型的类就尽量不要使用早期提供的非泛型类型的类。下面的泛型类型对应于低版本提供的类型: 泛型类 低版本提供的非泛型类 List ArrayList Dictionary Hashtable Queue Queue Stack Stack SortedList SortedList第42页/共53页实验中用到的泛型 SortedList :按键排序的键值对集合,是运算复杂度为 O(log n) 的二进制搜索树 。

29、 常用方法: Add方法:将带有指定键和值的元素添加到SortedList 中 例如(注意:如果插入重复的键会产生异常):SortedList openWith = new SortedList(); openWith.Add(txt, notepad.exe); openWith.Add(bmp, paint.exe); 第43页/共53页实验中用到的泛型(续) 如何遍历泛型列表中的每个键值对 SortedList list=new SortedList (); list.Add(a, 123); list.Add(b, 234); list.Add(c, 456); foreach (st

30、ring str in list.Keys) Console.WriteLine(key is : + str + ,value is :+liststr.ToString(); 第44页/共53页实验中用到的泛型(续) TryGetValue方法:获取与指定的键相关联的值 。例如:string value = ; if (openWith.TryGetValue(tif, out value) Console.WriteLine(For key = tif, value = 0., value); else Console.WriteLine(Key = tif is not found.); 第45

温馨提示

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

评论

0/150

提交评论