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

下载本文档

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

文档简介

1、1 1 第第4 4章章 面向对象的高级编程面向对象的高级编程 封装、继承与多态封装、继承与多态 版本控制版本控制 接口接口 委托委托 泛型处理泛型处理 2 2 本章教学目的本章教学目的 介绍面向对象高级编程的相关知识,使学生对介绍面向对象高级编程的相关知识,使学生对C#C#高级编程有高级编程有 一个感性认识。一个感性认识。 本章教学要求本章教学要求 (1 1)掌握继承、泛型的概念及基本用法;)掌握继承、泛型的概念及基本用法; (2 2)掌握与实验有关的相关内容,包括封装、继承与多态、)掌握与实验有关的相关内容,包括封装、继承与多态、 泛型处理泛型处理 ; (3 3)了解其他内容。)了解其他内容

2、。 3 3 实验中的问题解答实验中的问题解答 如何添加某个事件(例如窗体的如何添加某个事件(例如窗体的ShownShown事件)?如何删除某个事件?事件)?如何删除某个事件? 答:添加和删除事件均在设计视图下利用属性中的事件完成。答:添加和删除事件均在设计视图下利用属性中的事件完成。 使用使用textBoxStartAmount.Focus(); textBoxStartAmount.Focus(); 与使用与使用键让某控件获取焦点有键让某控件获取焦点有 何不同?何不同? 答:前者用于动态设置,后者用于静态设置。答:前者用于动态设置,后者用于静态设置。 实验实验2 2: private dou

3、ble Caculate(double startAmount, double rate, int private double Caculate(double startAmount, double rate, int count)count)叠加次数叠加次数countcount是什么意思?是什么意思? 答:叠加次数是指到期后将计算出来的利息作为存款再次计算,例如存答:叠加次数是指到期后将计算出来的利息作为存款再次计算,例如存 款时间为款时间为1 1年,则按年算息叠加次数为年,则按年算息叠加次数为1 1,按月算息叠加次数为,按月算息叠加次数为1212,按季,按季 度算息叠加次数为度算息叠加次

4、数为4 4。 实验报告什么时候交?进度如何安排?实验报告什么时候交?进度如何安排? 答:各人根据自己的情况安排进度,完成一个,写一个实验报告。答:各人根据自己的情况安排进度,完成一个,写一个实验报告。 如何定义属性?如何给属性赋值?如何获取属性的值?如何定义属性?如何给属性赋值?如何获取属性的值? 答:见书上答:见书上P59P59例例3-103-10 4 4 4.1 4.1 封装、继承与多态封装、继承与多态 封装:隐藏调用者不需要了解的信息。封装:隐藏调用者不需要了解的信息。 继承:简化类的设计。继承:简化类的设计。 多态:类为名称相同的方法提供不同实现方式的能力。多态:类为名称相同的方法提供

5、不同实现方式的能力。 5 5 封装封装 模块信息通过类封装模块信息通过类封装 类的成员通过字段、属性、方法、事件封装类的成员通过字段、属性、方法、事件封装 u私有的用私有的用privateprivate u可以被继承的用可以被继承的用protectedprotected u公共成员用公共成员用publicpublic u不要为了方便把什么都定义成不要为了方便把什么都定义成publicpublic u不要为了方便把什么都定义成不要为了方便把什么都定义成staticstatic 通过属性进行封装的例子:通过属性进行封装的例子:P73P73例例4-14-1 6 6 封装举例:封装举例: 对象封装了对

6、象的数据以及对这些数据的操作。 对象是属性和操作的组合 对象的表现(服务、接口)和实现细节分开 7 7 /MyClass.cs/MyClass.cs using System;using System; namespace ConsoleTestnamespace ConsoleTest class MyClass class MyClass private int number; private int number; public int Number public int Number get get return number; return number; set set if (v

7、alue 0) if (value 0) number = value; number = value; /Program.cs/Program.cs using System;using System; namespace ConsoleTestnamespace ConsoleTest public class Program public class Program public static void Main() public static void Main() MyClass me = new MyCl MyClass me = new MyCl ass();ass(); me.

8、Number = -1; me.Number = -1; Console.WriteLine( Console.WriteLine( Number:0, me. Number:0, me. Number);Number); Console.ReadLine(); Console.ReadLine(); 回答:回答:NumberNumber输出的值是多少?输出的值是多少? 8 8 练习练习(1)(1) Question 47. (Question 47. (单选单选) ) In Object oriented Programming, how would you In Object orient

9、ed Programming, how would you describe encapsulation?describe encapsulation? 1. The conversion of one type of object to another.1. The conversion of one type of object to another. 2. The runtime resolution of method calls.2. The runtime resolution of method calls. 3. The exposition of data.3. The ex

10、position of data. 4. The separation of interface and implementation.4. The separation of interface and implementation. 答案:答案:4 4 9 9 继承继承 继承表示现实世界中遗传关系的直接模继承表示现实世界中遗传关系的直接模 拟。拟。 它表示类之间的内在联系以及对属性和它表示类之间的内在联系以及对属性和 操作的共享。操作的共享。 10 10 继承(续)继承(续) 声明扩充类的语法:声明扩充类的语法: 访问修饰符访问修饰符 class class 扩充类名称:基类名称扩充类名称

11、:基类名称 / /程序代码程序代码 扩充类继承了所有定义在基类中数据的定义和方法。但扩充类继承了所有定义在基类中数据的定义和方法。但 是是扩充类不继承基类的构造函数扩充类不继承基类的构造函数。 继承的例子(继承的例子(1 1):):P76P76例例4-24-2 两种实现继承的方式:类继承和接口继承。两种实现继承的方式:类继承和接口继承。 类继承只允许单一继承类继承只允许单一继承 ,接口可实现多重继承。,接口可实现多重继承。 被继承的类叫基类被继承的类叫基类 继承自其他类的类叫扩充类继承自其他类的类叫扩充类 11 11 多态多态 用相同的操作名在一个类层次的不同类中实现不同用相同的操作名在一个类

12、层次的不同类中实现不同 的功能,相同的消息由同一的功能,相同的消息由同一( (父父) )类的不同对象接收类的不同对象接收 时,导致不同的行为。时,导致不同的行为。 举例:几何图形类层次中的多态性。其派生类“圆”、“长 方形”、“三角形”等都有方法“求面积”。 几何图形 圆三角形 几何图形 圆 ShapeShape类类 GetArea() RectangleRectangle类类 GetArea() CircleCircle类类 GetArea() TriangleTriangle类类 GetArea() 12 12 1 1、虚拟方法、虚拟方法 在基类中,如果想让某个方法或者事件被扩充类在基类中

13、,如果想让某个方法或者事件被扩充类 重写,可以使用修饰符重写,可以使用修饰符virtualvirtual表明:表明: public public virtualvirtual void myMethod() void myMethod() /程序代码程序代码 扩充类则用扩充类则用overrideoverride重写重写: : public public overrideoverride void myMethod() void myMethod() /程序代码程序代码 多态(续)多态(续) 13 13 /MyClass.cs/MyClass.cs using System;using Syst

14、em; namespace ConsoleTestnamespace ConsoleTest class MyClass class MyClass public virtual void Hello() public virtual void Hello() Console.WriteLine(123); Console.WriteLine(123); /MyNewClass.cs/MyNewClass.cs using System;using System; namespace ConsoleTestnamespace ConsoleTest class MyNewClass : MyC

15、lass class MyNewClass : MyClass private string str = hello private string str = hello ; public override void Hello() public override void Hello() Number = 2; Number = 2; Console.WriteLine(str); Console.WriteLine(str); 14 14 多态(续)多态(续) 使用虚拟方法和重写方法时,要注意下面几个方面:使用虚拟方法和重写方法时,要注意下面几个方面: 虚拟方法不能声明为静态的。虚拟方法不

16、能声明为静态的。 VirtualVirtual不能和不能和privateprivate一起使用。一起使用。 重写方法的名称、参数个数、类型以及返回值都必须和重写方法的名称、参数个数、类型以及返回值都必须和 虚拟方法的一致。虚拟方法的一致。 举例举例 P79P79页例页例4-44-4 15 15 多态(续)多态(续) 2 2、隐藏基类的方法、隐藏基类的方法 在扩充类中,可以使用在扩充类中,可以使用newnew关键字来隐藏基类的方法,关键字来隐藏基类的方法, 即使用一个完全不同的方法取代旧的方法。即使用一个完全不同的方法取代旧的方法。 与方法重写不同的是,使用与方法重写不同的是,使用newnew关

17、键字时并不要求基关键字时并不要求基 类中的方法声明为类中的方法声明为virtualvirtual,只要在扩充类的方法前声明,只要在扩充类的方法前声明 为为newnew,就可以隐藏基类的方法。,就可以隐藏基类的方法。 16 16 多态(续)多态(续) 3 3、抽象类、抽象类 使用使用abstractabstract修饰符。修饰符。 抽象类只能做基类。抽象类只能做基类。 抽象类与非抽象类的区别:抽象类与非抽象类的区别: 第一是抽象类不能直接被实例化,只能在扩充类中通第一是抽象类不能直接被实例化,只能在扩充类中通 过继承使用,对抽象类使用过继承使用,对抽象类使用newnew运算符会产生编译时错误运算

18、符会产生编译时错误 第二个不同点是抽象类可以包含抽象成员,而非抽象第二个不同点是抽象类可以包含抽象成员,而非抽象 类不能包含抽象成员。当从抽象类派生非抽象类时,这类不能包含抽象成员。当从抽象类派生非抽象类时,这 些非抽象类必须具体实现所继承的所有抽象成员。些非抽象类必须具体实现所继承的所有抽象成员。 17 17 补充题目补充题目 Question 32. (Question 32. (单选单选) ) 以下描述错误的是()以下描述错误的是() 1.1.在在C+C+中支持抽象类而在中支持抽象类而在C#C#中不支持抽象类。中不支持抽象类。 2.C+2.C+中可在头文件中声明类的成员而在中可在头文件中

19、声明类的成员而在CPPCPP文件中定义类文件中定义类 的成员,在的成员,在C#C#中没有头文件并且在同一处声明和定义类的中没有头文件并且在同一处声明和定义类的 成员。成员。 3.3.在在C#C#中可使用中可使用 new new 修饰符显式隐藏从基类继承的成员。修饰符显式隐藏从基类继承的成员。 4.4.在在C#C#中要在派生类中重新定义基类的虚函数必须在前面中要在派生类中重新定义基类的虚函数必须在前面 加加OverrideOverride。 18 18 练习(练习(2 2) abstract class BaseClassabstract class BaseClass public virtu

20、al void MethodA() public virtual void MethodA() Console.WriteLine(BaseClass);Console.WriteLine(BaseClass); class Class1: BaseClassclass Class1: BaseClass public void MethodA() public void MethodA() Console.WriteLine(Class1);Console.WriteLine(Class1); class Class2: Class1class Class2: Class1 在在MainMa

21、in方法中执行下列语句:方法中执行下列语句: Class2 Class2 o = new Class2();o = new Class2(); o.MethodA(); o.MethodA(); 问:执行结果是什么?问:执行结果是什么? 19 19 4.2 4.2 版本控制版本控制 用用C#C#编写方法时,如果在扩充类中重写基类的方法,编写方法时,如果在扩充类中重写基类的方法, 需要用需要用overrideoverride声明;要隐藏基类的方法,需要用声明;要隐藏基类的方法,需要用newnew声明,声明, 这就是这就是C#C#进行版本控制的依据。进行版本控制的依据。 调用非虚拟方法时不会受到版

22、本的影响调用非虚拟方法时不会受到版本的影响 调用虚拟方法的实现部分可能会因扩充类的重写而影响执调用虚拟方法的实现部分可能会因扩充类的重写而影响执 行结果。行结果。 举例:举例: P83 P83 例例4-84-8 P84 P84 例例4-94-9 20 20 4.2 4.2 版本控制(续)版本控制(续) 调用原则:调用继承的最后实现部分的方法调用原则:调用继承的最后实现部分的方法 P85 P85 例例4-104-10 C#C#允许派生类包含与基类方法名称相同的方法,规则如下:允许派生类包含与基类方法名称相同的方法,规则如下: 1)1) 基类方法必须声明为基类方法必须声明为virtualvirtu

23、al 2)2)若派生类中方法前无若派生类中方法前无newnew或或overrideoverride关键字,方法执行按存关键字,方法执行按存 在在newnew关键字一样执行关键字一样执行 3)3)若派生类中方法前带若派生类中方法前带newnew关键字,则此方法被定义为独立于关键字,则此方法被定义为独立于 基类的方法基类的方法 4)4)若派生类中方法前带若派生类中方法前带overrideoverride关键字,则派生类调用此方法,关键字,则派生类调用此方法, 而非基类的方法。而非基类的方法。 5)5)可从派生类中使用可从派生类中使用basebase关键字调用基类方法。关键字调用基类方法。 21 2

24、1 补充知识:补充知识:C#C#面试题面试题 public class A public class A public A() public A() Console.WriteLine( Console.WriteLine(“A A”);); public virtual void Fun() public virtual void Fun() Console.WriteLine(A.Fun()Console.WriteLine(A.Fun() ); ); public class B: A public class B: A public B() public B() Console.Wri

25、teLine( Console.WriteLine(“B B”); ); public new void Fun() 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()() 22 22 4.3 4.3 接口接口 接口的主要特点是

26、只有声明部分,没有实现部分。接口的主要特点是只有声明部分,没有实现部分。 接口成员的实现是通过类完成的。接口成员的实现是通过类完成的。 定义在接口中的方法都是定义在接口中的方法都是publicpublic的。的。 使用使用interfaceinterface关键字声明一个接口。常用的语法是:关键字声明一个接口。常用的语法是: 访问修饰符访问修饰符 interface interface 接口名称接口名称 / / 接口体接口体 一般情况下,以大写的一般情况下,以大写的“I I”开头指定接口名,表明这是开头指定接口名,表明这是 一个接口。一个接口。 需要在不相关的类中实现同样的功能时,可以使用接口

27、。需要在不相关的类中实现同样的功能时,可以使用接口。 23 23 4.3 4.3 接口接口 P88 P88 例例4-114-11 显示方式实现接口显示方式实现接口 例例4-124-12 注意:显示实现接口时,不能通过类的实例进行访问,注意:显示实现接口时,不能通过类的实例进行访问, 而必须使用接口实例。而必须使用接口实例。 通过接口实现多继承通过接口实现多继承 例例4-134-13 24 24 补充知识:补充知识:C#C#面试题面试题 不定项选择题不定项选择题 以下叙述正确的是:以下叙述正确的是: A. A. 接口中可以有虚方法。接口中可以有虚方法。 B. B. 一个类可以实现多个接口。一个类

28、可以实现多个接口。 C. C. 接口不能被实例化。接口不能被实例化。 D. D. 接口中可以包含已实现的方法。接口中可以包含已实现的方法。 B、C (2)(2)以下叙述正确的是:以下叙述正确的是: A. A. 接口和抽象类一样均只能声明,而不能有实现部分。接口和抽象类一样均只能声明,而不能有实现部分。 B. B. 类可以继承多个接口,但仅能从一个抽象类或其它类型的单个类继类可以继承多个接口,但仅能从一个抽象类或其它类型的单个类继 承。承。 C. C. 接口中可以定义属性、方法和事件,但只声明不实现。接口中可以定义属性、方法和事件,但只声明不实现。 D. D. 类的多继承可以通过接口实现。类的多

29、继承可以通过接口实现。 B、C、D 25 25 4.4 4.4 委托委托 类似与类似与C+C+中的函数指针,但有很大不同中的函数指针,但有很大不同 委托的声明委托的声明 例如:例如: publicpublic delegatedelegate void FuncDelegatevoid FuncDelegate(stringstring strstr);); 委托的使用委托的使用 具体内容不再详细讲述具体内容不再详细讲述 26 26 4.5 4.5 序列化与反序列化序列化与反序列化 序列化序列化 获取对象并将其状态信息转换为可存储或可传输形式的过程。获取对象并将其状态信息转换为可存储或可传输形

30、式的过程。 反序列化反序列化 将对象还原回序列化之前的内容。将对象还原回序列化之前的内容。 序列化和反序列化是一个互逆的过程。序列化和反序列化是一个互逆的过程。 .NET Framework.NET Framework提供的两种序列化技术提供的两种序列化技术 二进制序列化二进制序列化 XMLXML和和SOAPSOAP序列化序列化 27 27 4.5 4.5 序列化与反序列化序列化与反序列化 1 1、如何序列化一个类:在类的上方加上、如何序列化一个类:在类的上方加上SerializableSerializable特性即可。特性即可。 SerializableSerializable public

31、 class MyClass public class MyClass 2 2、二进制序列化、二进制序列化 MyClass user = new MyClass();MyClass user = new MyClass(); IFormatter formater = new BinaryFormatter(); IFormatter formater = new BinaryFormatter(); Stream stream = new FileStream(UserInfo.bin, FileMode.Create, Stream stream = new FileStream(User

32、Info.bin, FileMode.Create, FileAccess.Write, FileShare.None); FileAccess.Write, FileShare.None); formater.Serialize(stream, user);formater.Serialize(stream, user); stream.Close(); stream.Close(); 特点:特点: 二进制序列化会将一个类的所有成员变量都进行序列化,包括私有变量、二进制序列化会将一个类的所有成员变量都进行序列化,包括私有变量、 公共属性、方法等。公共属性、方法等。 28 28 4.5 4.5

33、 序列化与反序列化序列化与反序列化 3 3、二进制反序列化、二进制反序列化 IFormatter formatter = new BinaryFormatter();IFormatter formatter = new BinaryFormatter(); Stream stream = new FileStream(UserInfo.bin, Stream stream = new FileStream(UserInfo.bin, FileMode.Open, FileAccess.Read, FileShare.Read); FileMode.Open, FileAccess.Read,

34、FileShare.Read); MyClass c = (MyClass)formatter.Deserialize(stream);MyClass c = (MyClass)formatter.Deserialize(stream); stream.Close(); stream.Close(); 特点:特点: 反序列化后,对象反序列化后,对象c c与序列化之前的状态完全相同。与序列化之前的状态完全相同。 29 29 补充:二进制序列化与反序列化举例补充:二进制序列化与反序列化举例 保存窗体位置、颜色与数据库连接信息设置保存窗体位置、颜色与数据库连接信息设置 30 30 补充:二进制序列化

35、与反序列化举例补充:二进制序列化与反序列化举例 当输入服务器等信息、改变窗体前景色、位置后,退出应用当输入服务器等信息、改变窗体前景色、位置后,退出应用 程序,再次启动,可看到仍然是退出前的状态。程序,再次启动,可看到仍然是退出前的状态。 31 31 4.5 4.5 序列化与反序列化序列化与反序列化 4 4、XMLXML序列化序列化 (1 1)XML XML 序列化仅将对象的公共字段和属性值序列化为序列化仅将对象的公共字段和属性值序列化为XMLXML流,而不转换流,而不转换 方法、索引器、私有字段或只读属性(只读集合除外)。方法、索引器、私有字段或只读属性(只读集合除外)。 (2 2)XML

36、XML 序列化不包括类型信息,即不能保证序列化后的对象在被反序序列化不包括类型信息,即不能保证序列化后的对象在被反序 列化时,变为同一类型的对象。列化时,变为同一类型的对象。 (3 3)XMLXML序列化的实现步骤序列化的实现步骤 Class1 user = new Class1();Class1 user = new Class1(); user.AccountName = aa;user.AccountName = aa; XmlSerializer mySerializer = new XmlSerializer(typeof(Class1);XmlSerializer mySerial

37、izer = new XmlSerializer(typeof(Class1); StreamWriter myWriter = new StreamWriter(UserInfo.xml);StreamWriter myWriter = new StreamWriter(UserInfo.xml); mySerializer.Serialize(myWriter, user);mySerializer.Serialize(myWriter, user); myWriter.Close();myWriter.Close(); 32 32 4.5 4.5 序列化与反序列化序列化与反序列化 (4

38、4)XMLXML反序列化的步骤反序列化的步骤 Class1 c;Class1 c; XmlSerializer mySerializer = new XmlSerializer(typeof(Class1);XmlSerializer mySerializer = new XmlSerializer(typeof(Class1); FileStream myFileStream =FileStream myFileStream = new FileStream(UserInfo.xml, FileMode.Open); new FileStream(UserInfo.xml, FileMode

39、.Open); c = (Class1) mySerializer.Deserialize(myFileStream);c = (Class1) mySerializer.Deserialize(myFileStream); myFileStream.Close();myFileStream.Close(); 注意:注意: 反序列化一个对象时不会调用构造函数,这一点与创建对象不同。反序列化一个对象时不会调用构造函数,这一点与创建对象不同。 33 33 4.6 4.6 泛型处理泛型处理 泛型(泛型(GenericGeneric)一般用在集合和在集合上运行的方法)一般用在集合和在集合上运行的方法

40、中。中。.NET.NET框架框架2.02.0以前的版本不支持泛型。以前的版本不支持泛型。 使用泛型具有以下明显的使用泛型具有以下明显的优点优点: 1)1)可以避免以下两个问题:内部实现代码冗余和困扰开发人可以避免以下两个问题:内部实现代码冗余和困扰开发人 员的含混不清的编译器错误提示员的含混不清的编译器错误提示; ; 2)2)类型安全类型安全; ; 3)3)二进制代码重用二进制代码重用; ; 4)4)性能性能; ; 5)5)清晰性。清晰性。 34 34 4.6 4.6 泛型问题描述泛型问题描述 public class Stack public class Stack object m_Ite

41、ms; object m_Items; public void Push(object item) . public void Push(object item) . public object Pop() . public object Pop() . 使用举例:使用举例: Stack stack = new Stack();Stack stack = new Stack(); stack.Push(1);stack.Push(1); int number=(int)stack.Pop();int number=(int)stack.Pop(); stack.Push(stack.Push(

42、“strstr”);); string str=(string)stack.Pop();string str=(string)stack.Pop(); 35 35 基于基于ObjectObject的堆栈缺点的堆栈缺点 性能问题性能问题 值类型需频繁地装箱、拆箱,造成较多的垃圾碎片,增值类型需频繁地装箱、拆箱,造成较多的垃圾碎片,增 加垃圾回收的负担加垃圾回收的负担 引用类型需要强制类型转换引用类型需要强制类型转换 类型安全问题(更严重)类型安全问题(更严重) 编译时任务类型都转换成编译时任务类型都转换成objectobject,无法保证运行时类型,无法保证运行时类型 安全。安全。 例如:例如:

43、Stack stack = new Stack();Stack stack = new Stack(); stack.Push(“abc”); stack.Push(“abc”); int number = (int)stack.Pop();int number = (int)stack.Pop(); 36 36 4.6 4.6 泛型解决办法泛型解决办法 public class IntStack public class IntStack int m_Items;int m_Items; public void Push(int item) public void Push(int item

44、) . public int Pop() 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() . . 功能相似,代码冗余!维护麻烦! 37 37 基于基于Object的的 堆堆栈栈 IntStack StringStack 代码冗余, 维护复杂

45、, 工作效率低 性能问题、 类型安全问 题 有没有好的解决办法? 有,泛型 38 38 解决方法采用泛型解决方法采用泛型 public class public class Stack Stack T m_Items; T m_Items; public void Push(T item) public void Push(T item) . public T Pop() public T Pop() . . 39 39 泛型是如何实现的?泛型是如何实现的? 在在.NET 2.0.NET 2.0中,泛型在中,泛型在ILIL(中间语言)和(中间语言)和CLRCLR 本身中具有本机支持本身中具有本

46、机支持 编译泛型时,就像编译类一样,泛型仅保留编译泛型时,就像编译类一样,泛型仅保留 一个一个占位符占位符。 而用特定类型实例化的泛型代码,编译时会而用特定类型实例化的泛型代码,编译时会 将泛型替换为实例化的特定类型。将泛型替换为实例化的特定类型。 40 40 泛型实现泛型实现 public class Stack public class Stack T m_Items; T m_Items; public void Push(T item) . public void Push(T item) . public T Pop() . public T Pop() . 使用举例:使用举例: S

47、tack stack = new StackStack stack = new Stack stack.Push(1);stack.Push(1); int number = stack.Pop();int number = stack.Pop(); 41 41 泛型的定义和引用泛型的定义和引用 泛型定义代码语法如下:泛型定义代码语法如下: 访问修饰符访问修饰符返回类型返回类型 泛型支持类型泛型支持类型 泛型名称泛型名称 其中其中CLRCLR支持的泛型类、结构、方法、接口和委托等。支持的泛型类、结构、方法、接口和委托等。 泛型类定义举例:泛型类定义举例:class Nodeclass Node

48、 T data; T data; Node next; Node next; 例例4-19 4-19 引用泛型类引用泛型类 42 42 泛型的引用泛型的引用 泛型类定义举例:泛型类定义举例: void Swap(ref T item1, ref T item2)void Swap(ref T item1, ref T item2) T temp = item1; T temp = item1; item1 = item2; item1 = item2; item2 = temp; item2 = temp; 例例4-20 4-20 引用一个泛型方法引用一个泛型方法 程序举例:使用泛型方法来实现

49、程序举例:使用泛型方法来实现intint、doubledouble、floatfloat类型类型 的数据交换方法。的数据交换方法。 43 43 常用泛型常用泛型 凡是有对应泛型类型的类就尽量不要使用早期提供的非泛凡是有对应泛型类型的类就尽量不要使用早期提供的非泛 型类型的类。下面的泛型类型对应于低版本提供的类型:型类型的类。下面的泛型类型对应于低版本提供的类型: 泛型类泛型类 低版本提供的非泛型类低版本提供的非泛型类 ListList ArrayList ArrayList Dictionary Hashtable Dictionary Hashtable Queue Queue Queue

50、Queue Stack Stack Stack Stack SortedListSortedList SortedList SortedList 44 44 实验中用到的泛型实验中用到的泛型 SortedList SortedList :按键排序的键值对集合,是运算:按键排序的键值对集合,是运算 复杂度为复杂度为 O(log n) O(log n) 的二进制搜索树的二进制搜索树 。 常用方法:常用方法: AddAdd方法:将带有指定键和值的元素添加到方法:将带有指定键和值的元素添加到SortedList SortedList 中中 例如(注意:如果插入重复的键会产生异常):例如(注意:如果插入

51、重复的键会产生异常): SortedList openWith = new SortedListstring, SortedList openWith = new SortedList(); string(); openWith.Add(txt, notepad.exe); openWith.Add(txt, notepad.exe); openWith.Add(bmp, paint.exe); openWith.Add(bmp, paint.exe); 45 45 实验中用到的泛型(续)实验中用到的泛型(续) 如何遍历泛型列表中的每个键值对如何遍历泛型列表中的每个键值对 SortedList

52、 list=new SortedList list=new SortedList ();SortedList (); list.Add(a, 123); list.Add(a, 123); list.Add(b, 234); list.Add(b, 234); list.Add(c, 456); list.Add(c, 456); foreach (string str in list.Keys) foreach (string str in list.Keys) Console.WriteLine(key is : + str + Console.WriteLine(key is : + s

53、tr + ,value is :+liststr.ToString();,value is :+liststr.ToString(); 46 46 实验中用到的泛型(续)实验中用到的泛型(续) TryGetValueTryGetValue方法:获取与指定的键相关联的值方法:获取与指定的键相关联的值 。 例如:例如: string value = ; string value = ; if (openWith.TryGetValue(tif, out value)if (openWith.TryGetValue(tif, out value) Console.WriteLine(For key = tif, value = 0., value); Console.WriteLine(For key = tif, value = 0., value); else else Console.WriteLine(Key = tif is not found.); Console.WriteLine(Key = tif is not found.); 47 47 实验中用到的泛型(续)实验中用到的泛型(续) ContainsKey ContainsKey 方法:确定方法:确定 Sorted

温馨提示

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

评论

0/150

提交评论