《第6章接口和抽象类.ppt》由会员分享,可在线阅读,更多相关《第6章接口和抽象类.ppt(28页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、现在学习的是第1页,共28页学习目标学习目标v使用接口定义多个类的规范并在类中实现接口;使用接口定义多个类的规范并在类中实现接口;v使用抽象类定义所有派生类的公共定义,并在使用抽象类定义所有派生类的公共定义,并在派生类中实现抽象成员。派生类中实现抽象成员。第第六六章章 接接口口和和抽抽象象类类现在学习的是第2页,共28页6.1 接口【学一学学一学】v接口的定义接口的定义 C#中,接口也是一种数据类型,所以对接口的定义相当于定义一个新的数据类型,接口定义的语法格式如下:接口修饰符 interface 接口名 接口的成员;其中接口修饰符跟普通的类的修饰符含义一致,可以为public和interna
2、l。interface是接口定义的关键字,接口名是符合C#语法的标识符,一般接口名以”I”开头。接口的成员只可以是属性、方法、事件或者索引,且只是说明而没有实现,而不允许含有数据成员变量、构造函数、析构函数或静态成员。接口中的成员默认被声明为public的,在成员前不得加任何访问修饰符。第第六六章章 接接口口和和抽抽象象类类6.1.1 接口的定义和实现接口的定义和实现现在学习的是第3页,共28页6.1 接口v下列代码是一个定义接口的示例。interface IPict /定义了一个名为IPict的接口,该接口有两个成员 int Sides(get;);/定义一个属性成员Sides,来读取图形的
3、边数 float Area();/定义一个方法成员Area(),该方法返回图形的面积 v从上述代码中可以看到,接口IPict的两个成员仅有定义而没有实现,它告诉实现该接口的类或结构必须实现属性Sides和方法Area()。第第六六章章接接口口和和抽抽象象类类6.1.1 接口的定义和实现接口的定义和实现现在学习的是第4页,共28页6.1 接口 二接口的实现二接口的实现 类或者结构如果要实现接口,则要在定义的类名或结构名后添加冒号和接口名;如果要实现多个接口,则接口名依次列出,中间用逗号分开,接口名的前后次序没有要求。当一个类既要继承一个基类又要实现接口时,基类放在所有接口的前面。类实现接口的语法
4、格式如下所示:类访问修饰符 class 类名:基类,接口名列表 类实现接口的代码;第第六六章章 接接口口和和抽抽象象类类6.1.1 接口的定义和实现接口的定义和实现现在学习的是第5页,共28页6.1 接口下面的类Rect实现了上述接口IPict。class Rect:IPict /表示类Rect必须实现接口IPict int width,height;/定义类的两个私有成员,表示矩形的宽和高 public Rect(int w,int h)w=width;h=height;public float Area()/实现接口IPict中定义的方法Area,返回矩形的面积 return width*
5、height;第第六六章章接接口口和和抽抽象象类类6.1.1 接口的定义和实现接口的定义和实现现在学习的是第6页,共28页6.1 接口v在定义完Rect类后,就可以象普通类一样创建类的实例,然后通过实例访问实现的方法Area和属性Sides。v在接口定义完后,虽然不能对接口实例化,但是也可以声明接口类型的实例,此时可以将实现该接口的类的对象引用赋给接口类型实例,通过该实例访问接口中的成员,间接调用类对接口中的成员实现。如下列代码就是将类的对象赋值给接口实例,并访问实例的成员。public void InterfaceInstance()IPict ipict;/声明接口实例 ipict=new
6、 Rect(5,4);/接口实例引用Rect对象 Console.WriteLine(ipict.Area();/通过接口调用类实现的成员方法 Console.WriteLine(ipict.Sides);/通过接口调用类实现的成员属性 第第六六章章 接接口口和和抽抽象象类类6.1.1 接口的定义和实现接口的定义和实现现在学习的是第7页,共28页6.1 接口 一般情况下,如果类实现了一个接口,则可以通过类的实例访问该类实现的接口成员。但有些情况比较复杂,例如一个类同时实现两个接口,这两个接口中都声明了同名的方法,此时在类实现接口成员时,就必须在成员前加上相关的接口名,来指明该成员属于哪个接口,
7、这种情况称为显式接口。在访问显式接口的成员时,不能通过类实例,只能通过接口实例来访问。v例如下列两个接口IstuReg、IStaffReg都声明了具有相同方法签名的方法Register。interface IStuReg/学生注册接口 void Register(string name,int age,int no);interface IStaffReg/职员注册接口 void Register(string name,int age,int no);第第六六章章接接口口和和抽抽象象类类6.1.2 显示接口显示接口现在学习的是第8页,共28页6.1 接口v下列类Trainee表示一个实习生类
8、,该类实现了上述两个接口。class Trainee:IStaffReg,IStuReg string name;int age;int stuno;int workno;/以下代码实现接口IStaffReg中的Register方法 void IStaffReg.Register(string name,int age,int no)name=name;age=age;workno=no;/以下代码实现接口IStuReg中的Register方法第第六六章章接接口口和和抽抽象象类类6.1.2 显示接口显示接口现在学习的是第9页,共28页6.1 接口 void IStuReg.Register(s
9、tring name,int age,int no)name=name;age=age;stuno=no;v如果要调用实习生类Trainee中的Register方法,则必须通过接口实例来访问这些方法,如下列代码所示。static void Main(string args)IStuReg obj1=new Trainee();/使接口IstuReg类型的实例obj引用Trainee实例 obj1.Register(lisi,30,3210);/调用Trainee类实现的IStuReg接口中的Register方法 IStaffReg obj2=new Trainee();obj2.Registe
10、r(zhangsan,30,3320);第第六六章章接接口口和和抽抽象象类类6.1.2 显示接口显示接口现在学习的是第10页,共28页6.1 接口 在C#中,可以将接口作为方法的参数或返回值来使用。当接口作为方法的参数时,表明对应的参数应该是实现该接口的一个类的实例,例如集合类System.Collections.ArrayList中方法BinarySearch的一个重载形式就将接口作为参数来使用,该方法的一个原型如下:public virtual int BinarySearch(Object value,IComparer comparer);而接口作为方法的返回值是表明该方法返回一个实现
11、该接口的类的实例,例如集合类System.Collections.HashTable中的方法GetEnumerator有如下一种原型:public virtual IDictionaryEnumerator GetEnumerator();第第六六章章接接口口和和抽抽象象类类6.1.3 接口作为参数和返回值接口作为参数和返回值现在学习的是第11页,共28页6.1 接口【试一试】任务6-1:定义一个教师晋升职称后提高工资的接口和一个员工类(说明:每个员工都有姓名、工号和薪水),再定义一个教授类和一个讲师类,他们分别继承员工类和实现接口,并能调用各自的方法Print输出教授或讲师的姓名、工号和薪水
12、。解决思路:1.定义晋升接口IPromote,该接口中声明一个方法Promote;2.定义类Employee;3.定义类Professor,该类继承类Employee并实现接口IPromote,并添加方法Print;4.定义类Lecturer,该类继承类Employee并实现接口IPromote,并添加方法Print;5.在主方法Main中创建类Professor和Lecturer的实例,并调用方法Promote和Print来提高工资和输出教授和讲师的基本信息。第第六六章章接接口口和和抽抽象象类类6.1.3 接口作为参数和返回值接口作为参数和返回值现在学习的是第12页,共28页6.1 接口完成
13、步骤:1.创建一个名为“chapter6_1”的控制台应用程序。2.在项目中添加一个接口类文件IPromote.cs,接口IPromote定义如下:interface IPromote void Promote();3.在项目中添加一个类文件Employee.cs,类Employee的内容如下:class Employee/员工类 protected string name;/姓名 protected string no;/工号 protected float salary;/薪水 第第六六章章 接接口口和和抽抽象象类类6.1.3 接口作为参数和返回值接口作为参数和返回值现在学习的是第13页,
14、共28页6.1 接口 protected Employee(string name,string no,float salary)this.name=name;this.no=no;this.salary=salary;4.在项目中添加一个类文件Professor.cs,类Professor的内容如下:class Professor:Employee,IPromote public Professor(string name,string no,float salary):base(name,no,salary)/调用基类的构造函数 this.name=name;第第六六章章接接口口和和抽抽象
15、象类类6.1.3 接口作为参数和返回值接口作为参数和返回值现在学习的是第14页,共28页6.1 接口 this.no=no;this.salary=salary;/实现接口IPromotable中声明的方法Promote public void Promote()salary*=2;public void Print()/输出教授的基本信息 Console.WriteLine(教授姓名:0,工号:1,薪水¥:2,name,no,salary);第第六六章章接接口口和和抽抽象象类类6.1.3 接口作为参数和返回值接口作为参数和返回值现在学习的是第15页,共28页6.1 接口 5.在项目中添加一个
16、类文件Lecturer.cs,类Lecturer的内容如下:class Lecturer:Employee,IPromote public Lecturer(string name,string no,float salary):base(name,no,salary)/调用基类的构造函数 this.name=name;this.no=no;this.salary=salary;/实现接口IPromotable中声明的方法Promote public void Promote()salary*=1.4f;第第六六章章 接接口口和和抽抽象象类类6.1.3 接口作为参数和返回值接口作为参数和返回值
17、现在学习的是第16页,共28页6.1 接口 public void Print()/输出讲师的基本信息 Console.WriteLine(讲师姓名:0,工号:1,薪水¥:2,name,no,salary);v6.在主方法Main中编写如下代码,创建类Professor和类Lecturer的实例,并分别调用各自的方法Promote和Print,来提高薪水和输出员工的基本信息。static void Main(string args)Professor liyang=new Professor(李杨,001,2500);Lecturer zhanghui=new Lecturer(张辉,002,
18、2500);liyang.Promote();zhanghui.Promote();liyang.Print();zhanghui.Print();第第六六章章 接接口口和和抽抽象象类类6.1.3 接口作为参数和返回值接口作为参数和返回值现在学习的是第17页,共28页6.1 接口 7.编译和执行程序。执行程序后,运行结果如图6.1所示。第第六六章章 接接口口和和抽抽象象类类6.1.3 接口作为参数和返回值接口作为参数和返回值图6.1 输出教授和讲师的基本信息 现在学习的是第18页,共28页6.2 抽象类【学一学】v抽象类的主要作用是提供公共定义,供派生类共享。抽象类的公共成员只有通过派生类的对
19、象才能访问,抽象类是不能被实例化的。定义一个抽象类很简单,只需要在定义类的关键字class之前添加abstract就可以了,如下所示:访问修饰符 abstract class 类名 /类成员v抽象类可以包含抽象方法,所谓抽象方法是指:在声明方法时,方法返回类型的前面添加关键字 abstract,该方法就称为抽象方法。其语法格式是:v访问修饰符 abstract 返回类型 方法(参数列表);v抽象方法不需实现,即不需要写方法体。而抽象类的派生类必须实现所有抽象方法。如果一个类含有一个或一个以上的抽象成员(抽象方法或抽象属性),则该类必须定义为抽象类。v在抽象类中,既可包含一般方法,也可包含抽象方
20、法,但须注意的是,抽象类可以不包含抽象成员。如以下代码就定义了一个抽象类第第六六章章接接口口和和抽抽象象类类6.2.1 抽象类的定义抽象类的定义现在学习的是第19页,共28页6.2 抽象类Animal,该类既包含一般方法Eat,也含有抽象方法Run。public abstract class Animal /定义抽象类Animal protected float length;/身长 protected float weight;/体重 protected Animal(float length,float weight)this.length=length;this.weight=weigh
21、t;public void Eat()Console.WriteLine(动物都要吃食物!);public abstract void Run();/表示动物奔跑的抽象方法 第第六六章章接接口口和和抽抽象象类类6.2.1 抽象类的定义抽象类的定义现在学习的是第20页,共28页6.2 抽象类v抽象类中的抽象方法或属性只有声明,而没有实现,在派生类中必须重写该方法或属性。重写抽象方法或属性时,要用到关键字override。下列类Dog就实现了上述抽象类Animal的抽象方法Run。public class Dog:Animal public Dog(float length,float weigh
22、t):base(length,weight)this.length=length;this.weight=weight;public override void Run()/使用override关键字重写抽象类的抽象方法Run Console.WriteLine(狗会用4条腿奔跑!);第第六六章章接接口口和和抽抽象象类类6.2.2 抽象类的实现抽象类的实现现在学习的是第21页,共28页6.2 抽象类v重写抽象类中的方法后,就可以创建一个派生类的对象,来访问抽象方法的具体实现,如下列代码所示。Dog dog=new Dog(12.5f,56.4f);dog.Run();v抽象类虽然不能实例化,但
23、可以象接口一样声明抽象类实例,让其引用派生类的实例,然后通过抽象类实例调用其派生类的抽象方法的具体实现,如下列代码所示。Animal animal=new Dog(12,30);animal.Run();v除了在抽象类中定义抽象方法外,也可以定义抽象属性。关于属性的知识将在下一章进行介绍。抽象类不提供抽象属性的实现,只声明该类支持哪些属性,这些属性可以是只读、只写或可读写的,抽象属性的实现由派生类负责。抽象属性的定义和实现与抽象方法基本相同,在此不再赘述。第第六六章章接接口口和和抽抽象象类类6.2.2 抽象类的实现抽象类的实现现在学习的是第22页,共28页6.2 抽象类v接口是一种数据类型、是
24、一种特殊的类,抽象类也是一种特殊的类,它们具有类的一些特性。下面对两者做一比较,以便加深理解和灵活运用它们。第第六六章章 接接口口和和抽抽象象类类6.2.3 接口和抽象类的比较接口和抽象类的比较相同点不同点1)都属于引用类型的数据,是一种特殊的类;1)抽象类是由相似对象抽象而成的类,而接口只是一个行为的规范或规定。2)都不能实例化,必须在派生类中实现。2)一个类可以实现多个接口,但是只能从一个父类中派生,其中就包括抽象类。3)都可以包含未实现的方法声明和属性声明;3)抽象类既包含可变部分又包含不可变的部分,但接口仅定义了可变的部分。4)两者的派生类都必须实现它们的声明,派生类实现抽象类的抽象方
25、法和抽象属性,而对于接口而言,则要实现它的所有成员。4)如果要创建组件的多个版本,则应该创建抽象类;如果创建的功能在所有对象中使用,则应该创建接口。表6-1 接口和抽象类的比较现在学习的是第23页,共28页6.2 抽象类【试一试】任务6-2:在某企业中,员工薪水的计算方法是不同的。例如,销售人员的工资是员工基本工资加提成,管理人员的工资是基数乘以级别系数。现要求定义一个抽象的员工类和两个派生类来解决上述问题。其中抽象类包含一个用于计算员工薪水的抽象方法Earning、一个输出员工薪水的一般方法Print。解决思路:1.定义抽象类Employee;2.定义派生自抽象类Employee的销售员类S
26、eller,;3.定义派生自抽象类Employee的管理人员类Manager;4.在主方法中分别创建类Seller、Manager的实例,计算薪水和输出结果。完成步骤:1.创建一个名为“Chapter6_2”的控制台应用程序。2.在项目中添加一个类文件Employee.cs,抽象类Employee的定义如下:第第六六章章接接口口和和抽抽象象类类6.2.3 接口和抽象类的比较接口和抽象类的比较现在学习的是第24页,共28页6.2 抽象类 abstract class Employee protected string name,no;/员工姓名和工号 protected float salary
27、;/员工薪水 protected Employee(string name,string no,float salary)/构造函数 this.name=name;this.no=no;this.salary=salary;abstract public void Earning();/计算薪水的抽象方法 public void Print()/输出员工的信息 Console.WriteLine(0的工号是:1,薪水总计为:2,name,no,salary);第第六六章章接接口口和和抽抽象象类类6.2.3 接口和抽象类的比较接口和抽象类的比较现在学习的是第25页,共28页6.2 抽象类 3.在
28、项目中添加一个类文件Seller.cs,类Seller的定义如下:class Seller:Employee/派生自类Employee float rate;/提成比例 float sale;/销售总额 public Seller(string name,string no,float salary,float sale,float rate):base(name,no,salary)this.name=name;this.no=no;this.salary=salary;this.rate=rate;this.sale=sale;public override void Earning()/
29、重写抽象方法Earning salary+=(sale-5000)*rate;第第六六章章接接口口和和抽抽象象类类6.2.3 接口和抽象类的比较接口和抽象类的比较现在学习的是第26页,共28页6.2 抽象类 4.在项目中添加一个类文件Manager.cs,类Manager的定义如下:class Manager:Employee/派生自类Employee float level;/薪水级别系数 public Manager(string name,string no,float salary,float level):base(name,no,salary)this.name=name;this
30、.no=no;this.salary=salary;this.level=level;public override void Earning()/重写抽象方法 salary*=level;第第六六章章接接口口和和抽抽象象类类6.2.3 接口和抽象类的比较接口和抽象类的比较现在学习的是第27页,共28页6.2 抽象类 该类的定义与类Seller基本相同,不同之处是计算薪水的方法不同,该类人员没有销售提成,只有薪水级别系数。5.在主方法Main中编写如下代码,分别创建类Seller、Manager的实例,调用方法Earning和Print来计算薪水和输出员工的基本信息。static void Main(string args)Seller huanghua=new Seller(黄华,001,1000,20000,0.1f);Manager liye=new Manager(李晔,002,1000,3.5f);huanghua.Earning();liye.Earning();huanghua.Print();liye.Print();执行程序,运行结果如图6.2所示。第第六六章章接接口口和和抽抽象象类类6.2.3 接口和抽象类的比较接口和抽象类的比较图6.2 员工的基本信息 现在学习的是第28页,共28页