收藏 分销(赏)

第五章接口及内部类.ppt

上传人:仙人****88 文档编号:13754416 上传时间:2026-04-10 格式:PPT 页数:104 大小:456.50KB 下载积分:10 金币
下载 相关 举报
第五章接口及内部类.ppt_第1页
第1页 / 共104页
第五章接口及内部类.ppt_第2页
第2页 / 共104页


点击查看更多>>
资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,第五章 接口和内部类,前几章,我们学习,了,c#,面向对象编程的所有基本工具。这一章,我们要介绍两种高级技巧接口和内部类。尽管掌握起来有点难度,但很有必要去掌握他们,以便去完善你的,c#,工具箱。,接口和内部类为我们提供了一种用来组织和控制系统中的对象的更加精致的方法。,前面我们学习了有关,abstract,关键字的知识,该关键字允许人们在类中创建一个或多个没有任何定义的方法(只提供了方法名,却没有提供具体的实现),而这些实现是由此类的继承者创建的。但抽象类还是无法完全抽象,因为他拥有非抽象的字段和方法。,在,c#,中接口不是类,而是一组对类的要求(契约),你可以认为是:接口是用来描述类的功能(像一个商品的说明书和承诺书),而不指明具体的实现方式。只要类实现了接口,就可以在任何需要该接口的地方使用这个类的对象。当别人一看到类实现的接口时,就知道这个类一定会满足某些标准。,interface(,接口)这个关键字产生了一个完全抽象的类,他根本就没有提供任何具体实现的方法。他不仅仅是只是一个极度抽象的类,还是允许人们通过创建一个能够被更多的类向上转型到的基类的类,来实现某种类似,c+,多重继承变种的特性,因为在,c#,中一个类可以实现一个或多个接口.,接口,在,c#,中,接口不是类,而是一组对类的要求,接口就像是一份合同,谁实现了该接口,就必须按照接口中定义的方式方法去实现,不能违背,这时这些实现了接口的类就拥有了和接口中定义的一样的行为。,往往你在很多的,c#,书籍中可以看到这么一句话:“如果你的类遵循了一个特定接口,那么我们就可以执行某种服务了”,正因为类实现某个接口,其他的类就相信他实现某种功能。,1.,interface,关键字使,abstract,的概念更向前迈进了一步,你可以将,interface,看成“纯粹的”抽象类。他为实现他的类创建其拥有的基本结构(行为和特征方法和字段)。,2.在接口中所有的方法只有方法名,参数列表和返回类型,但是没有任何的方法体的若干方法(即只提供了形式,却没有提供具体实现)。,3.接口不能包含字段(实例或静态)和实例方法,接口的成员为:方法,属性,事件和索引器,要提供实例字段和方法实现,那是实现了接口的类的任务,现在你可以把接口认为是抽象类的特殊版本。,4.要想创建一个接口,需要用,interface,关键字代替,class,关键字,就像类一样。可以在,interface,关键字前面添加,public,关键字。,EG:public,interface,接口名;,要想让一个类遵循某个特定接口(或者是一组接口).需要使用,:,关键字,:,class Car:,接口名,当一个类实现了一个接口,类就必须覆盖掉接口中定义的所有方法-重写,接口中定义的方法的具体内容(因为接口中定义的方法没有具体实现方法的具体内容)且覆盖的方法的修饰符号必须是,public(,因为覆盖的方法(子类中定义的)的修饰符号一定要大于或等于被覆盖的父类的方法的修饰符。,接口中的任何方法的修饰符自动是,public,的,因此,在接口中声明方法不能使用,public,关键字修饰,即接口成员不能带有可见性级别,也不需要用,virtual,或,abstract,关键字修饰。,那么怎样定义一个接口,又怎样才能实现了一个接口呢?我们来看一个具体的程序。,范例:,using System;,public class,Love,public static void Main(,String args),康泰克,myhetong=,new,康泰克();,Console.WriteLine(myhetong);,myhetong.,止痛();,;,interface,ISO,证书,/定义一个接口,void,止痛();,/在接口中的任何方法都不能实现具体细节,class,康泰克:,ISO,证书,/一个类实现一个接口,public void,止痛(),/不需加,override,关键字,必须覆盖掉接口中定义的方法,/必须实现接口中定义的所有方法,Console.WriteLine(,通过调节神经系统来缓解疼痛);,public override string ToString(),return,康泰克;,;,程序制作:,侄女完成作业的程序编写。,我们通过接口,就可以强制一个类必须使用某些我们要求的方法,通过上面的程序我们能了解到接口的使用方式和接口特点(总结),1:,interface,接口名 来定义一个接口,。,2:当,类要实现一个接口,就必须要通过,:,来实现一个接口(签合同);,3:当一个非抽象类实现了一个接口,类就必须覆盖掉接口中定义的所有方法-重写接口中定义的方法的具体内容(因为接口中定义的方法没有具体实现方法的具体内容.,4:抽象类也可以实现接口,但必须在抽象类中使用,abstract,重新设置接口中定义的方法或覆盖接口中方法,即可以为实例方法或抽象方法。,5:在接口中我们的定义的所有方法都不能使用,public,修饰符,这是因为系统会在所有的接口的方法前加上,public,然而,在实现一个接口时(在类中覆盖接口中定义的方法时),你必须为类中的方法使用,public,修饰符号,否则,编译器将报出错误。,6:范例:,了解抽象类和接口的关系。,using System;,public class,Love,public static void Main(string args),C c=,new,C();,c.getA();,c.getB();,c.getI();,public interface,I,void getI();,public abstract class,A:I,public abstract void getA();,public abstract void getI();,/,这样就可以,public abstract class,B:A,public abstract void getB();,public class,C:B,/,必须将上面的接口和抽象父类中的所有抽象方法覆盖掉,public override void getI(),Console.WriteLine(,这是接口中的,getI();,public override void getA(),Console.WriteLine(,这是父类-,A,中的,getA();,public override void getB(),Console.WriteLine(,这是父类-,B,的,getB();,程序设计,为教育总局指定今年学雷锋计划要求,要求每个学校必须履行,但具体实施的办法由学校自做决定。请你为五月花所有的分校指定参与的合同。,范例:,using System;,using System.IO;,class,love,public static void Main(),学校,x=,new,学校();,x.setName(,总校);,x.setAction(,维护校园清洁);,Console.WriteLine(x);,x.,学雷锋();,学校,x1=,new,学校();,x1.setName(,五块石);,x1.setAction(,维护交通安全);,Console.WriteLine(x1);,x1.,学雷锋();,public interface,教育总局,void,学雷锋();,public class,学校:教育总局,private string name;,public void setName(string n),this.name=n;,public string getName(),return name;,private string action;,public void setAction(string a),this.action=a;,public string getAction(),return action;,public void,学雷锋(),Console.WriteLine(,帮助贫困学生);,if(action!=null),Console.WriteLine(action);,public override string ToString(),return,学校的名字:+,name;,问题1:以上程序中的教育总局能用抽象类实现吗?,问题2:如果教育总局换成社会公益事业,并且要求学校和企业必须履行学雷锋的计划,该如何编写程序呢?,问题3:请你在上面的程序中,设置一个检查机构,负责检查每个学校的执行情况。,解答问题:,1.,以上程序中的教育总局能用抽象类,因为抽象类也可以使用抽象方法保证其子类有其对应的覆盖方法,其二:教育总局和学校可以建立上司和下属的关系(能产生继承的关系),2.如果教育总局换成社会公益事业,并且要求学校和企业必须履行学雷锋的计划的话,社会公益事业将不能使用抽象类来完成了,必须用接口,因为学校,企业和社会公益事业没有继承关系,学校和企业本身也没有任何的关系。,总结:接口和抽象类如何选择:,接口可以针对不同的的事物定义要求,且接口中不能定义变量。,抽象类只能针对有关系的多个事物定义要求,能够定义变量。,增设一个检查机构,负责检查每个学校的执行情况。,范例:,using System;,using System.IO;,class,love,public static void Main(),监察机构,j=,new,监察机构();,学校,x=,new,学校();,x.setName(,总校);,x.setAction(,维护校园清洁);,Console.WriteLine(x);,x.,学雷锋();,学校,x1=,new,学校();,x1.setName(,五块石);,x1.setAction(,维护交通安全);,Console.WriteLine(x1);,x1.,学雷锋();,企业,q=,new,企业();,q.setName(,希望集团);,Console.WriteLine(,现在检查:);,j.,检查(,x);,j.,检查(,x1);,j.,检查(,q);,public class,监察机构,public void,检查(,教育总局,j),Console.WriteLine(j);,j.,学雷锋();,public interface,教育总局,void,学雷锋();,public class,企业:教育总局,private string name;,public void setName(string n),this.name=n;,public string getName(),return name;,private string action;,public void setAction(string a),this.action=a;,public string getAction(),return action;,public void,学雷锋(),Console.WriteLine(,捐资助学);,if(action!=null),Console.WriteLine(action);,public override string ToString(),return,企业的名字:+,name;,public class,学校:教育总局,private string name;,public void setName(string n),this.name=n;,public string getName(),return name;,private string action;,public void setAction(string a),this.action=a;,public string getAction(),return action;,public void,学雷锋(),Console.WriteLine(,帮助贫困学生);,if(action!=null),Console.WriteLine(action);,public override string ToString(),return,学校的名字:+,name;,范例:请你为飞机和鸟设计程序。-判断是用抽象类还是接口。,using System;,public class,Test,public static void Main(string args),Bird b=,new,Bird();,b.Fly();,飞机,f=,new,飞机();,f.Fly();,public interface,飞翔,void Fly();,public class,Bird:,飞翔,public void Fly(),Console.WriteLine(,靠翅膀飞翔);,public class,飞机:飞翔,public void Fly(),Console.WriteLine(,靠双翼加油门进行飞翔);,3.回答下面那些使用接口,哪些使用抽象类完成。,1.确保飞机和鸟有飞翔的动作。,2.确保企鹅和喜鹊有飞翔的动作。,3.取保机器人和汽车都有启动的动作。,接口中的向上转型和多态性,1.接口不是类,尤其是,绝不能使用,new,操作符实例化接口。,2.虽然不能构造接口对象,但还是可以声明接口变量。,eg,:,接口名 接口,3.接口变量只能接收一个实现了该接口的类的对象变量名;,接口变量名=,new,实现了此接口的类对象(.);,4.和子类向上转型成为父类一样,一旦类向上转换成他实现的接口后,类中定义的,但对于接口而言是新的方法都将被暂时屏蔽掉,即只能使用当前接口中定义的方法。此时当调用接口中的方法时,系统也会按照多态性的原理,自动搜寻类中覆盖后的方法版本。,5.我们来看一个程序:,using System;,public interface,I,void getI();,public class,H:I,public void getI(),Console.WriteLine(,接口中的方法);,public void getH(),Console.WriteLine(,H,类中新定义的方法);,public class,dodo,public static void Main(,String args),I i=,new,H();,i.getI();,/i.getH();,报错,无法寻找,我们再次利用前面的乐器类程序的思想结合接口,将前面的乐器类程序改编一下,程序如下,using System;,class,Note,/,音乐中的音符,private string noteName;,private Note(string noteName),this.noteName=noteName;,public override string ToString()return noteName;,public static readonly,Note MIDDLE_C=,new,Note(,Middle C),C_SHARP =,new,Note(,C Sharp),B_FLAT =,new,Note(,B Flat);,interface,Instrument,/Compile-time constant:,/Cannot have method definitions:,void play(,Note n);,/Automatically public,string what();,/,返回当前乐器的名字。,void adjust(,Note n);,/,表示调音,class,Wind:Instrument,public virtual void play(,Note n),Console.WriteLine(,Wind.play()+n);,public virtual string what()return,Wind;,public virtual void adjust(,Note n),Console.WriteLine(n);,class,Brass:Wind,public override void play(,Note n),Console.WriteLine(,Brass.play()+n);,public override void adjust(,Note n),Console.WriteLine(,Brass.adjust():+n);,class,Woodwind:Wind,public override void play(,Note n),Console.WriteLine(,Woodwind.play()+n);,public override string what()return,Woodwind;,public class,Music5,static void tune(,Instrument i),i.play(Note.MIDDLE_C);,i.adjust(Note.B_FLAT);,static void tuneAll(,Instrument e),for(int i=0;i e.Length;i+),tune(ei);,public static void Main(string args),/Upcasting during addition to the array:,Instrument orchestra=,new,Wind(),new,Brass(),new,Woodwind(),;,tuneAll(orchestra);,从这个程序,我们可以看出,一个实现了接口的类(和继承某个类的子类一样),其对象都可以向上转型为接口(让接口类型的变量指向对象)。这样使程序更加灵活。,课堂程序:,为解放军叔叔配置现代战争设备,要求:,1.军委规定:现代化的军人和现代化的战争设备必须具有现代化作战的必要条件:攻击敌人和骚扰敌人。,2.为解放军设计两种武器,电子干扰设备。,3.配置以后,当解放军攻击敌人时,他将使用所有配置的设备攻击敌人,当解放军骚扰敌人时,将使用所有配置的设备骚扰敌人。,范例:,using System;,public class,Test,public static void Main(,String args),解放军,ren=,new,解放军();,ren.setName(,song);,武器,AK47=,new,武器();,AK47.setName(,AK47);,电子设备,she=,new,电子设备();,she.setName(,网络电子攻击设备);,AK47.set,现代战争机器(,ren);,she.set,现代战争机器(,AK47);,/she.,显示();,/,she.,攻击敌人();,she.,骚扰敌人();,public interface,现代战争必要条件,/针对不同的设备定义合同,void,骚扰敌人();,void,攻击敌人();,void,显示();,public abstract class,攻击武器:现代战争必要条件,private string name;,public void setName(string n),this.name=n;,public string getName(),return name;,private,现代战争必要条件 现代战争机器;,public void set,现代战争机器(,现代战争必要条件,x),this.,现代战争机器=,x;,public virtual void,骚扰敌人(),if(this.,现代战争机器!=,null),this.,现代战争机器.骚扰敌人();,public virtual void,攻击敌人(),if(this.,现代战争机器!=,null),this.,现代战争机器.攻击敌人();,public virtual void,显示(),if(this.,现代战争机器!=,null),this.,现代战争机器.显示();,public class,武器:攻击武器,public override void,骚扰敌人(),base.,骚扰敌人();,Console.WriteLine(,使用武器:+,getName()+,阻止敌人进攻,突袭敌人);,public override void,攻击敌人(),base.,攻击敌人();,Console.WriteLine(,使用武器:+,getName()+,歼灭敌人);,public override void,显示(),base.,显示();,Console.WriteLine(,使用武器:+,getName();,public class,电子设备:攻击武器,public override void,骚扰敌人(),base.,骚扰敌人();,Console.WriteLine(,使用电子设备+,getName()+,阻止敌人的网络骚扰,换大家一片安静的天空);,public override void,攻击敌人(),base.,攻击敌人();,Console.WriteLine(,使用电子设备:+,getName()+,攻击对方网络,让他们感觉处处有唐僧,时时有唐僧,唐僧就在身边,唐僧是他们的一份子,人人喊:我爱唐僧);,public override void,显示(),base.,显示();,Console.WriteLine(,使用设备:+,getName();,public class,解放军:现代战争必要条件,private string name;,public void setName(string n),this.name=n;,public string getName(),return name;,public void,骚扰敌人(),Console.WriteLine(getName()+,将用武器骚扰敌人);,public void,攻击敌人(),Console.WriteLine(getName()+,将用智慧,设备,身体取打击敌人);,public void,显示(),Console.WriteLine(,我是一名军人:+,name);,程序设计(课后作业),请你设计一个继承链的层次结构,球类运动员-体育总局规定必备的训练方式为:跑步训练。,1.球类运动员羽毛运动员,2.球类运动员-足球运动员,在程序中需实现下列要求:(从要求中分析获取),1:每种球类运动员都必须进行必备的训练方式(跑步训练),2:每种球类运动员可以结合自身运动的特点具体确定跑步训练的形式(,eg,:,羽毛运动员可以进行折反跑,足球运动员可以进行3000米的速跑,),3:每一个球员都必须有自己的姓名,年龄。,4:羽毛运动员:有羽毛球运动员特有的,id,卡(必须是唯一的,且添加运动员时,id,卡号自动增加),进行搓球训练,5:足球运动员:有足球球运动员特有的,id,卡(必须是唯一的,且添加运动员时,id,卡号自动增加),进行射门训练,整个程序,using System;,using System.Collections;,public interface,XunLian,/,体育总局规定的球类运动员的必备训练方式为:跑步训练,string run();,public abstract class,QiuYun:XunLian,/,设计一个抽象类,目的是为了不要客户端产生此类的实例。,private string name;,private string age;,public abstract string run();,/,必须定义和接口同结构的方法,要么使用,abstract,,要么不加,abstract,,但必须实现。,public QiuYun(string n,string a),this.name=n;,this.age=a;,public string getName(),return name;,public string getAge(),return age;,public void setName(string n),this.name=n;,public void setAge(string a),this.age=a;,public class,YuYun:QiuYun,private int card;,/,羽毛球运动员的,id,卡,private static int id=1;,public YuYun(string n,string a):base(n,a),card=id;,id+;,public int getCard(),return card;,public void setCard(int c),this.card=c;,public string yuXun(),return,搓球训练;,public override string run(),return,折反跑;,public override string ToString(),return,羽毛球运动员:,id:+card+,姓名:+,base.getName()+,年龄:+,base.getAge()+,必备训练:+,run()+,特殊训练:+,yuXun();,class,ZuYun:QiuYun,private int card;,private static int id=1;,public ZuYun(string n,string a):base(n,a),this.card=id;,id+;,public int getCard(),return card;,public void setCard(int c),this.card=c;,public string yuXun(),return,射门训练;,public override string run(),return,3000,米速跑;,public override string ToString(),return,足球运动员:,id:+card+,姓名:+,base.getName()+,年龄:+,base.getAge()+,必备训练:+,run()+,特殊训练:+,yuXun();,public class,Love,public static void Main(string args),ArrayList a=,new,ArrayList();,a.Add(,new,YuYun(,song,25);,a.Add(,new,ZuYun(,jack,27);,a.Add(,new,YuYun(,xiao,26);,a.Add(,new,ZuYun(,letian,30);,for(int i=0;ia.Count;i+),Console.WriteLine(ai);,分析:,必备的训练方式(,跑步训练,)-采用接口完成.,球类运动员抽象类,并让其实现针对必备的训练方式的接口.,羽毛运动员,足球运动员分别用一个类表示.,c#,中内置的接口使用方式,当使用,Array,类,Sort,方法对对象数组进行排序时,,,但是必须满足如下前提:对象所属的类必须要实现,IComparable,接口,即数组中的每个元素均必须实现,IComparable,接口,才能与数组中的其他所有元素进行比较。,1.接口的介绍:,System,命名空间,IComparable,IComparable,接口以及其中的方法。,public interface,IComparable,int,CompareTo,(,Object,obj,);,这意味着任何实现了,IComparable,接口的类必须实现,CompareTo,方法,该方法必须使用一个,Object,做参数,并且返回一个整数。,注意:这个内置接口只有一个方法,而有些内置接口可以多个方法。,2.方法的含义:,int compareTo,(Object,otherObject,),1.,把调用此方法的对象和,otherObject,进行比较。,2.注意:对象本身是没有办法进行比较的,比较的依据将根据对象中所包含的某种数据-员工的工资,员工的工龄长短.)。默认情况是:如果本对象小于,otherObject,,,返回一个负整数(表示当前对象在排序后的数组中的位置在,otherObject,的前面),如果相等,则返回0,否则返回一个正整数(表示当前对象在排序后的数组中的位置在,otherObject,的后面)。,-注意,这种排序方式也可以颠倒过来。,使用方式:,1.将实现了,IComparable,接口的对象放入数组。,2.然后将数组放入,Array.Sort(),方法中进行排序时,系统将自动调用数组中每个对象的,CompareTo,(),方法,和其他对象做比较,从而进行对象的排序(排序方式将按,CompareTo,(),方法的定义来具体确定)。,下面我们将对所有的员工对象进行比较(按照员工的收入进行升序排列),using System;,using System.Collections;,public class,hhhh,public static void Main(string args),Employee staff=,new,Employee3;,staff0=,new,Employee(,Harry Hacker,35000);,staff1=,new,Employee(,Carl Cracker,75000);,staff2=,new,Employee(,Tony Tester,38000);,Array.Sort(staff);,/print out information about all Employee objects,for(int i=0;i staff.Length;i+),Employee e=staffi;,Console.WriteLine(,name=+e.getName(),+,salary=+e.getSalary();,class,Employee:IComparable,public Employee(string n,double s),name=n;,salary=s;,public string getName(),return name;,public double getSalary(),return salary;,public void raiseSalary(double byPercent),double raise=salary*byPercent/100;,salary+=raise;,/*,Compares employees by salary,param otherObject another Employee object,*/,public int CompareTo(,Object otherObject),Employee other=(Employee)otherObject;,if(salary other.salary)return 1;,return 0;,private string name;,private double salary;,程序全在此处,大家在看了此程序以后,思考一下如何实现按员工收入进行降序排列呢?,注意:上面程序可能会遇到几个问题,1:如果我们的数组中的元素是来源于,ArrayList,对象时,情况就有点不同了,因为,ArrayList,对象中存储的都是,Object,对象,所以在使用,CompareTo,比较的时候,就必须首先判断对象正确的类型,然后才能正确的进行向下转型,,此时我们可用:对象名,.,GetType,(),或,is,关键字来做出判断。,2:我们可以像使用,is,判断对象是否属于某个类那样,使用,is,来,判断一个对象是不是属于某个实现了一个接口的类,这样在对象向上转型后,就可以准确的调用接口中定义的方法来调用对象中的方法。,eg,:,if(object is,IComparable,),3:,当类的对象向上转型成为他实现的接口类型的变量后,当进行向下转型时,我们也可以利用 接口变量名.,GetType(,),方法或,is,关键字来判断接口变量所指向的对象到底是属于哪个类。,注意:在,C#,中,可以通过:接口变量名.,GetType().ToString(),得到接口对应的对象实际的类的名字,即如果接口指向的是实现此接口的类的对象,,GetType().ToString(),方法此对象实际的类型名字。,我们通过程序来看一下以上第三点所讲到的操作方式:,using System;,public interface,I,void getI();,public class,Xin:I,public void getI(),Console.WriteLine(,Xin.getI();,public class,dodo,public static void Main(string args),I x=,new,Xin();,/x.getI();,if(x.GetType().ToString().Equals(,Xin),Console.WriteLine(,GetType(),方法成功判断);,Xin xx=(Xin)x;,xx.getI();,if(x is,Xin),Console.WriteLine(,is,关键字成功判断);,Xin xx=(Xin)x;,xx.getI();,程序设计,于是上面的程序改编一下,1:使用数组列表,ArrayList,,,可以存放任何的对象。,2:,检查数组列表中的对象是否实现了某个接口。,3:如果比较双方都是员工,则按员工薪水由高到低排列。,范例:,using System;,using System.Collections;,public class,Love,public static void Main(string args),ArrayList staff1=,new,ArrayList();,staff1.Add(,new,Employee(,Harry Hacker,35000);,staff1.Add(,new,Employee(,Carl Cracker,75000);,staff1.Add(,new,DateTime();,staff1.Add(,new,Employee(,Tony Tester,38000);,Object staff=staff1.ToArray();,Array.Sort(staff);,/print out information about all Employee objects,for(int i=0;i staff.Length;i+),if(staffi is,IComparable&staffi,is,Employee),Employee e=(Employee)staffi;,Console.WriteLine(,name=+e.getName(),+,salary=+e.getSalary();,else,Console.WriteLine(,其他类的对象,类型为0,描述为1,staffi.GetType().ToString(),staffi);,class,Employee:IComparable,public Employee(string n,double s),name=n;,salary=s;,public string getName(),return name;,public double getSalary(),return salary;,public void raiseSalary(double byPercent),double raise=salary*byPercent/100;,salary+
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服