《第9章面向对象高级技术.ppt》由会员分享,可在线阅读,更多相关《第9章面向对象高级技术.ppt(31页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、课程主讲人:第9章 面向对象高级技术9.1 抽象类与抽象方法抽象类与抽象方法9.2 接口接口9.3 密封类与密封方法密封类与密封方法9.4 迭代器迭代器9.5 分部类分部类9.6 泛型泛型虚方法是有方法体的,当父类中的这个方法完全无法确定方法体的时虚方法是有方法体的,当父类中的这个方法完全无法确定方法体的时候,就可以使用另外一种形式来表现,这种形式叫抽象方法。抽象方法候,就可以使用另外一种形式来表现,这种形式叫抽象方法。抽象方法的返回值类型前用关键字的返回值类型前用关键字abstract修饰,且无方法体,抽象方法必须存修饰,且无方法体,抽象方法必须存在于抽象类中。在于抽象类中。抽象类与非抽象类
2、的主要区别:抽象类与非抽象类的主要区别: 抽象类不能直接实例化;抽象类不抽象类不能直接实例化;抽象类不能是密封类;抽象类中可以包含抽象成员,但是非抽象类中不可以。能是密封类;抽象类中可以包含抽象成员,但是非抽象类中不可以。访问修饰符访问修饰符 abstract class 类名称类名称 : 基类或者接口基类或者接口成员修饰符成员修饰符 类的成员变量或者成员函数类的成员变量或者成员函数【实例实例9-1】抽象类抽象类Employee和具体类和具体类MREmployeepublic abstract class Employee /抽象类 private string strCode = ; pri
3、vate string strName = ; public string Code /编号属性及实现 get return strCode; set strCode = value; public string Name /姓名属性及实现 get return strName; set strName = value; /抽象方法,用来输出信息 public abstract void Work();【实例实例9-1】抽象类抽象类Employee和具体类和具体类MREmployeepublic class HREmployee : Employee /继承抽象类 public overrid
4、e void Work() /重写抽象类中输出信息的方法 Console.WriteLine(工号: + Code + ,姓名: + Name+,工作内容是招聘员工。); public class TecEmployee : Employee /继承抽象类 public override void Work() /重写抽象类中输出信息的方法 Console.WriteLine(工号: + Code + ,姓名: + Name + ,工作内容是研发产品。); 【实例实例9-1】抽象类抽象类Employee和具体类和具体类MREmployeeclass Program /测试类 static vo
5、id Main(string args) Employee emp = null; /声明抽象类的引用 emp = new HREmployee(); /实例化派生类HREmployee emp.Code = HR1000; /使用抽象类对象访问抽象类中的编号属性 emp.Name = 张三; /使用抽象类对象访问抽象类中的姓名属性 emp.Work(); /使用抽象类对象调用派生类中的方法 emp = new TecEmployee(); /实例化派生类TecEmployee emp.Code = Tec1000;/使用抽象类对象访问抽象类中的编号属性 emp.Name = 李四; /使用抽
6、象类对象访问抽象类中的姓名属性 emp.Work(); /使用抽象类对象调用派生类中的方法 图9-1 抽象方法和抽象类的使用接口使用接口使用interface关键字定义,不使用关键字定义,不使用class关键字。关键字。接口有以下几个特点:接口有以下几个特点:(1)接口类似于抽象类:继承接口的任何非抽象)接口类似于抽象类:继承接口的任何非抽象类型必须实现接口中的所有成员。类型必须实现接口中的所有成员。(2)不能够直接实例化接口。)不能够直接实例化接口。(3)类、接口可以从多个接口继承。)类、接口可以从多个接口继承。 访问修饰符访问修饰符 interface interface 接口名称:接口名
7、称: 继承的接口列表继承的接口列表 接口内容接口内容 【实例实例9-2】声明接口声明接口IStudentinterface IStudent string StudentCode /编号(可读可写) get; set; string StudentName /姓名(可读可写) get; set; void ShowInfoOfStudent();/显示定义的编号和姓名 如果类实现两个接口,并且这两个接口包含具有相如果类实现两个接口,并且这两个接口包含具有相同签名的成员,那么在类中实现该成员,将会导致两同签名的成员,那么在类中实现该成员,将会导致两个接口都使用该成员作为它们的实现。个接口都使用该
8、成员作为它们的实现。这时可以显式的实现接口成员,即创建一个仅仅透这时可以显式的实现接口成员,即创建一个仅仅透过该接口调用并且特定于该接口的类成员。过该接口调用并且特定于该接口的类成员。显式接口成员实现是使用接口名称和一个句点命名显式接口成员实现是使用接口名称和一个句点命名该类成员来实现的。该类成员来实现的。【实例9-4】显示实现接口ICalculate1和ICalculate2class Compute : ICalculate1, ICalculate2 /继承接口 / 实现求和方法 int ICalculate1.Add() /显式接口成员实现 int x = 10; int y = 40
9、; return x + y; / 实现求和方法 int ICalculate2.Add() /显式接口成员实现 int x = 10; int y = 40; int z = 50; return x + y + z; interface ICalculate1 int Add(); /求和方法,加法运算的和interface ICalculate2 int Add(); /求和方法,加法运算的和【实例实例9-3】实现实例】实现实例9-2中的接口中的接口IStudentclass Program static void Main(string args) Compute compute =
10、new Compute(); /实例化接口继承类的对象 ICalculate1 Cal1 = compute;/使用接口继承类的对象实例化接口 Console.WriteLine(Cal1.Add();/使用接口对象调用接口中的方法 ICalculate2 Cal2 = compute;/使用接口继承类的对象实例化接口 Console.WriteLine(Cal2.Add();/使用接口对象调用接口中的方法 图9-3 显式接口的使用接口的实现通过继承来实现,一个类虽然只能够继接口的实现通过继承来实现,一个类虽然只能够继承一个基类,但是可以继承多个接口。声明实现接口承一个基类,但是可以继承多个接
11、口。声明实现接口的类时,需要在继承的列表中包含类所实现接口的名的类时,需要在继承的列表中包含类所实现接口的名称。称。【实例实例9-3】实现实例】实现实例9-2中的接口中的接口IStudentclass Student : IStudent /继承接口 string strCode = ; string strName = ; / 编号 public string StudentCode get return strCode; set strCode = value; / 姓名 public string StudentName get return strName; set strName =
12、 value; /实现接口中定义的方法 public void ShowInfoOfStudent() Console.WriteLine(编号t 姓名); Console.WriteLine(StudentCode + t + StudentName); 【实例实例9-3】实现实例】实现实例9-2中的接口中的接口IStudentclass Program static void Main(string args) IStudent iStu = new Student(); /声明接口,引用到Student对象 iStu.StudentCode = S1000; /为派生类中的Code属性赋
13、值 iStu.StudentName = 孙悟空; /为派生类中的Name属性赋值 iStu.ShowInfoOfStudent(); /调用派生类中方法显示定义的属性值 图9-2 接口的使用如果不希望编写的类被继承,或者有的类已经没有如果不希望编写的类被继承,或者有的类已经没有再被继承的必要,可以使用再被继承的必要,可以使用sealed修饰符在类中进行修饰符在类中进行声明,以达到该类不能派生其它类的目的,该类就被声明,以达到该类不能派生其它类的目的,该类就被称为密封类。称为密封类。C#中声明密封类时需要使用中声明密封类时需要使用sealed关键字。关键字。【实例9-5】声明密封类Sealed
14、Classpublic sealed class SealedClass /声明密封类 public int i=0; public void method() Console.WriteLine(我是密封类); 密封方法只能用于对基类的虚方法进行实现,并提密封方法只能用于对基类的虚方法进行实现,并提供具体的实现。供具体的实现。声明密封方法时,声明密封方法时,sealed 修饰符总是和修饰符总是和 override 修修饰符同时使用。饰符同时使用。public class People public virtual void ShowInfoOfPeople() /虚方法,用来显示信息 【实例
15、9-6】虚方法ShowInfoOfPeople/声明密封类public sealed class Student : People /密封类,继承自People private string strCode = ; /string类型变量,用来记录编号 private string strName = ; /string类型变量,用来记录名称 public string Code /编号属性 get return strCode; set strCode = value; public string Name /名称属性 get return strName; set strName = va
16、lue; /密封并重写基类中的ShowInfoOfPeople方法 public sealed override void ShowInfoOfPeople() Console.WriteLine(这个学生的信息:n + Code + + Name); 【实例实例9-3】实现实例】实现实例9-2中的接口中的接口IStudentclass Program static void Main(string args) Student stu = new Student(); /实例化密封类对象 stu.Code = S1000;/为密封类中的编号属性赋值 stu.Name = 孙悟空; /为密封类中
17、的名称属性赋值 stu.ShowInfoOfPeople();/调用密封类中的密封方法 图9-5 密封方法的使用实现了实现了IEnumerator接口的类称为枚举器,包含了接口的类称为枚举器,包含了Current、MoveNext以及以及Reset函数成员。可枚举类是函数成员。可枚举类是指实现了指实现了IEnumerable接口的类,它只有一个成员接口的类,它只有一个成员GetEnmuerator方法,返回对象的枚举器。方法,返回对象的枚举器。迭代器代码使用迭代器代码使用yield return语句依次返回每个元素,语句依次返回每个元素,yield break将中止迭代。到达将中止迭代。到达y
18、ield return语句时,会语句时,会保存当前迭代的位置,下次调用迭代器时将从此位置保存当前迭代的位置,下次调用迭代器时将从此位置开始执行。开始执行。【实例实例9-7】使用默认迭代器使用默认迭代器public class Banks : IEnumerable /定义Banks类,继承IEnumerable接口 string strArray = 中国银行, 工商银行, 农业银行, 建设银行 ; public IEnumerator GetEnumerator() /实现接口中的方法 for (int i = 0; i strArray.Length; i+) yield return s
19、trArrayi; class Program public static void Main(string args) Banks banks = new Banks(); foreach (string str in banks) Console.WriteLine(str); 图9-6 迭代方法的使用分部类就是类拆分到两个或多个文件中,而编译时分部类就是类拆分到两个或多个文件中,而编译时会将所有分部编译在一起。会将所有分部编译在一起。声明分部类使用关键字声明分部类使用关键字partical,分部类之间可访,分部类之间可访问性,抽象、静态、都必须是相同。问性,抽象、静态、都必须是相同。各个
20、分部类之间可以相互调用其参数、方法等,各各个分部类之间可以相互调用其参数、方法等,各个分部类继承的接口和基类都是共同继承的。个分部类继承的接口和基类都是共同继承的。【实例实例8】声明分部类声明分部类CarPropertypartial class CarProperty public bool Move(int s) Accelerate(s); return true; partial void Accelerate(int s);partial class CarProperty partial void Accelerate(int s) Console.WriteLine(s.ToSt
21、ring() + 公里每小时已加速!); class Program static void Main(string args) CarProperty cp = new CarProperty(); cp.Move(5); 图9-7 分部类的使用泛型是在强类型程序设计语言中编写代码时定义一泛型是在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须具体化,是将类些可变部分,那些部分在使用前必须具体化,是将类型参数化以达到代码复用提高软件开发工作效率的一型参数化以达到代码复用提高软件开发工作效率的一种数据类型。种数据类型。泛型方法是指通过泛型来约束方法中的参数类型,泛型方法是指
22、通过泛型来约束方法中的参数类型,定义泛型方法需要在方法名和参数列表之间加上定义泛型方法需要在方法名和参数列表之间加上,并在其中使用并在其中使用 T 来代表参数类型。来代表参数类型。【实例实例9-9】泛型方法泛型方法Swapclass Program /这是一个泛型方法,可以在普通类中 public static void Swap(ref T t1, ref T t2) T temp = t1; t1 = t2; t2 = temp; public static void Main(string args) int a = 1; int b = 2; /调用泛型方法。也可以省略类型参数,编译器
23、将推断出该参数。 Swap(ref a, ref b); Console.WriteLine(整形数字交换后: + a + + b); string s1 = hello; string s2 = world; /调用泛型方法。也可以省略类型参数,编译器将推断出该参数。 Swap(ref s1, ref s2); Console.WriteLine(字符串交换后: + s1 + + s2); 图9-8 泛型方法的使用实例实例9-10】泛型类泛型类SumClassclass SumClass /T为未知的类型,可能是int,也可能是double private T a; private T b;
24、 public SumClass(T a, T b) /构造函数 this.a = a; this.b = b; public T GetSum() /因为下面用到了求和运算,所以先把参数转换为可变类型 dynamic v1 = a; dynamic v2 = b; return (T)(v1 + v2); 实例实例9-10】泛型类泛型类SumClassclass Program static void Main(string args) /当我们利用泛型类构造时,需要指定泛型的类型 SumClass sc1 = new SumClass(12, 34); int sum1 = sc1.GetSum(); Console.WriteLine(sum1); SumClass sc2= new SumClass(1.1f, 2.2f); float sum2 = sc2.GetSum(); Console.WriteLine(sum2); 图9-9 泛型类的使用