Java超详细透彻讲解接口
一、引入一方面有时必须从几个类中派生出一个子类继承它们所有的属性和方法。但是Java不支持多重继承。有了接口就可以得到多重继承的效果。另一方面有时必须从几个类中抽取出一些共同的行为特征而它们之间又没有is-a的关系仅仅是具有相同的行为特征而已。例如鼠标、键盘、打印机、扫描仪、摄像头、充电器、MP3机、手机、数码相机、移动硬盘等都支持USB连接。二、理解接口就是规范定义的是一组规则体现了现实世界中“如果你是/要…则必须能…”的思想。继承是一个是不是的关系而接口实现则是能不能的关系。接口的本质是契约标准规范就像我们的法律一样。制定好后大家都要遵守。三、使用接口使用关键字interface来定义。Java中接口和类是并列关系或者接口可以理解为一种特殊的类。从本质上讲接口是一种特殊的抽象类这种抽象类中只包含常量和方法的定义(JDK7.0及之前)而没有变量和方法的实现。定义Java类的语法格式先写extends后写implements1classSubClassextendsSuperClassimplementsInterfaceA{ }接口(interface)是抽象方法和常量值定义的集合。如何定义接口JDK7及以前只能定义全局常量和抽象方法接口中的所有成员变量都默认是由public static final修饰的可以省略不写。接口中的所有抽象方法都默认是由public abstract修饰的。代码演示123456publicinterfaceRunner {intID 1;//public static final int ID 1;voidstart();//public abstract void start();publicvoidrun();//public abstract void run();voidstop();//public abstract void stop();}JDK8除了定义全局常量和抽象方法之外还可以定义静态方法、默认方法。1.静态方法使用static关键字修饰。接口中定义的静态方法只能通过接口来调用并执行其方法体。我们经常在相互一起使用的类中使用静态方法。你可以在标准库中找到像Collection/Collections或者Path/Paths这样成对的接口和类。2.默认方法默认方法使用default关键字修饰。可以通过实现类对象来调用。我们在已有的接口中提供新方法的同时还保持了与旧版本代码的兼容性。比如java 8 API中对Collection、List、Comparator等接口提供了丰富的默认方法。若一个接口中定义了一个默认方法而另外一个接口中也定义了一个同名同参数的方法不管此方法是否是默认方法在实现类同时实现了这两个接口时会出现接口冲突。 解决办法实现类必须覆盖接口中同名同参数的方法来解决冲突。若一个接口中定义了一个默认方法而父类中也定义了一个同名同参数的非抽象方法那么子类在没有重写此方法的情况下默认调用的是父类中的同名同参数的方法不会出现冲突问题。因为此时遵守类优先原则。接口中具有相同名称和参数的默认方法会被忽略。如何在子类(或实现类)的方法中调用父类、接口中被重写的方法?代码演示11234567publicvoidmyMethod(){method3();//调用自己定义的重写的方法super.method3();//调用的是父类中声明的//调用接口中的默认方法CompareA.super.method3();CompareB.super.method3();}代码演示21234567891011121314151617181920212223interfaceFilial {// 孝顺的defaultvoidhelp() {System.out.println(老妈我来救你了);}}interfaceSpoony {// 痴情的defaultvoidhelp() {System.out.println(媳妇别怕我来了);}}classFather{publicvoidhelp(){System.out.println(儿子就我媳妇);}}classManextendsFatherimplementsFilial, Spoony {Overridepublicvoidhelp() {System.out.println(我该就谁呢);Filial.super.help();Spoony.super.help();}}接口中不能定义构造器的意味着接口不可以实例化。接口采用多继承机制。可以实现多个接口 弥补了Java单继承性的局限性。格式class AA extends BB implements CC,DD,EE;Java开发中接口通过让类去实现(implements)的方式来使用。如果实现类覆盖了接口中的所有抽象方法则此实现类就可以实例化 。如果实现类没有覆盖接口中所有的抽象方法则此实现类仍为一个抽象类。代码演示123456789101112131415/*实现类SubAdapter必须给出接口SubInterface以及父接口MyInterface中所有方法的实现。否则SubAdapter仍需声明为abstract的。*/interfaceMyInterface{String s“MyInterface”;publicvoidabsM1();}interfaceSubInterfaceextendsMyInterface{publicvoidabsM2();}publicclassSubAdapterimplementsSubInterface{publicvoidabsM1(){System.out.println(“absM1”);}publicvoidabsM2(){System.out.println(“absM2”);}}接口与接口之间可以继承而且可以多继承。一个类可以实现多个无关的接口。代码演示12345678interfaceRunner {publicvoidrun();}interfaceSwimmer {publicdoubleswim();}classCreator{publicinteat(){…}}classManextendsCreatorimplementsRunner ,Swimmer{publicvoidrun() {……}publicdoubleswim() {……}publicinteat() {……}}与继承关系类似接口与实现类之间存在多态性代码演示123456789101112publicclassTest{publicstaticvoidmain(String args[]){Test t newTest();Man m newMan();t.m1(m);t.m2(m);t.m3(m);}publicString m1(Runner f) { f.run(); }publicvoidm2(Swimmer s) {s.swim();}publicvoidm3(Creator a) {a.eat();}}接口的匿名实现类匿名对象代码演示1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465publicclassUSBTest {publicstaticvoidmain(String[] args) {Computer com newComputer();//1.创建了接口的非匿名实现类的非匿名对象Flash flash newFlash();com.transferData(flash);//2. 创建了接口的非匿名实现类的匿名对象com.transferData(newPrinter());//3. 创建了接口的匿名实现类的非匿名对象USB phone newUSB(){Overridepublicvoidstart() {System.out.println(手机开始工作);}Overridepublicvoidstop() {System.out.println(手机结束工作);}};com.transferData(phone);//4. 创建了接口的匿名实现类的匿名对象com.transferData(newUSB(){Overridepublicvoidstart() {System.out.println(mp3开始工作);}Overridepublicvoidstop() {System.out.println(mp3结束工作);}});}}classComputer{publicvoidtransferData(USB usb){//USB usb new Flash();usb.start();System.out.println(具体传输数据的细节);usb.stop();}}interfaceUSB{//常量定义了长、宽、最大最小的传输速度等voidstart();voidstop();}classFlashimplementsUSB{Overridepublicvoidstart() {System.out.println(U盘开启工作);}Overridepublicvoidstop() {System.out.println(U盘结束工作);}}classPrinterimplementsUSB{Overridepublicvoidstart() {System.out.println(打印机开启工作);}Overridepublicvoidstop() {System.out.println(打印机结束工作);}}四、应用-代理模式(Proxy)1. 应用场景安全代理屏蔽对真实角色的直接访问。远程代理通过代理类处理远程方法调用RMI。延迟加载先加载轻量级的代理对象真正需要再加载真实对象比如你要开发一个大文档查看软件大文档中有大的图片有可能一个图片有100MB在打开文件时不可能将所有的图片都显示出来这样就可以使用代理模式当需要查看图片时用proxy来进行大图片的打开。2. 分类静态代理静态定义代理类动态代理动态生成代理类3. 代码演示12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485//举例一interfaceNetwork {publicvoidbrowse();}// 被代理类classRealServerimplementsNetwork {Overridepublicvoidbrowse() {System.out.println(真实服务器上网浏览信息);}}// 代理类classProxyServerimplementsNetwork {privateNetwork network;publicProxyServer(Network network) {this.network network; }publicvoidcheck() {System.out.println(检查网络连接等操作);}publicvoidbrowse() {check();network.browse();}}publicclassProxyDemo {publicstaticvoidmain(String[] args) {Network net newProxyServer(newRealServer());net.browse();}}//举例二publicclassStaticProxyTest {publicstaticvoidmain(String[] args) {Proxy s newProxy(newRealStar());s.confer();s.signContract();s.bookTicket();s.sing();s.collectMoney();}}interfaceStar {voidconfer();// 面谈voidsignContract();// 签合同voidbookTicket();// 订票voidsing();// 唱歌voidcollectMoney();// 收钱}//被代理类classRealStarimplementsStar {publicvoidconfer() {}publicvoidsignContract() {}publicvoidbookTicket() {}publicvoidsing() {System.out.println(明星歌唱~~~);}publicvoidcollectMoney() {}}//代理类classProxyimplementsStar {privateStar real;publicProxy(Star real) {this.real real;}publicvoidconfer() {System.out.println(经纪人面谈);}publicvoidsignContract() {System.out.println(经纪人签合同);}publicvoidbookTicket() {System.out.println(经纪人订票);}publicvoidsing() {real.sing();}publicvoidcollectMoney() {System.out.println(经纪人收钱);}}五、接口和抽象类之间的对比No.区别点抽象类接口1定义包含抽象方法的类主要是抽象方法和全局常量的集合2组成构造方法、抽象方法、普通方法、常量、变量常量、抽象方法、(jdk8.0:默认方法、静态方法)3使用子类继承抽象类(extends)子类实现接口(implements)4关系抽象类可以实现多个接口接口不能继承抽象类但允许继承多个接口5常见设计模式模板方法简单工厂、工厂方法、代理模式6对象都通过对象的多态性产生实例化对象都通过对象的多态性产生实例化对象7局限抽象类有单继承的局限接口没有此局限8实际作为一个模板是作为一个标准或是表示一种能力9选择如果抽象类和接口都可以使用的话优先使用接口因为避免单继承的局限如果抽象类和接口都可以使用的话优先使用接口因为避免单继承的局限六、经典题目(排错)1234567891011121314151617181920212223242526272829303132333435363738//题目一interfaceA {intx 0;}classB {intx 1;}classCextendsBimplementsA {publicvoidpX() {System.out.println(x);}publicstaticvoidmain(String[] args) {newC().pX();}}//题目二interfacePlayable {voidplay();}interfaceBounceable {voidplay();}interfaceRollableextendsPlayable, Bounceable {Ball ball newBall(PingPang);}classBallimplementsRollable {privateString name;publicString getName() {returnname;}publicBall(String name) {this.name name;}publicvoidplay() {ball newBall(Football);System.out.println(ball.getName());}}到此这篇关于Java超详细透彻讲解接口的文章就介绍到这了