接口的定义和类的定义很类似,能够分为接口声明和接口体积,和类不一样的是,使用关键字interface来声明本身是一个接口。
格式以下;
interface 接口的名字
这里须要注意的是:
一、若是一个非抽象类实现了某个接口,那么这个类必须重写这个接口中的全部方法。
二、若是一个类声明实现一个接口,可是没有重写接口中的从全部方法,那么这个类必须是抽象类,也就是说抽象类既能够重写接口中的方法,也能够直接拥有接口中的方法。
三、程序能够用接口名访问接口中的常量,可是若是一个类实现了接口,那么该类能够直接在类体中使用该接口的常量。
四、在咱们定义接口的时候,若是关键字interface 前面加一个public关键字,就成这样的接口是一个public接口,public接口能够被任何一个类实现。若是一个接口不加public修饰。就称做是友好接口,友好接口能够被 与该接口在同一个包中的类实现。
五、若是父类实现了某个接口,那么子类天然也就实现了该接口,子类没必要再显式地使用关键字implement声明实现这个接口。
六、接口也能够被继承,便可以经过关键字extends声明一个接口是另一个接口的子接口。因为接口中的方法和常量都是public的,子接口将继承父接口中的所有方法和常量。
举个例子吧:
在这个例子中China类和Japan类分别继承computable接口。
下面是具体的源代码:
China类java
1 package Example14; 2 3 import Example5.ComputerAver; 4 5 public class China exends Computable { 6 int number; 7 public int f(int x) { 8 //public关键字别漏了 9 int sum = 0; 10 for(int i=1; i<= x;i++){ 11 sum+=i; 12 } 13 return sum; 14 } 15 //重写方法f 16 }
Japan类编程
1 package Example14; 2 3 public class Japan extends Computable { 4 int number; 5 @Override 6 public int f(int x) { 7 return MAX + x; 8 //直接调用接口中的常量 9 } 10 11 }
computable接口ide
1 package Example14; 2 3 public interface Computable { 4 int MAX = 46; 5 public abstract int f(int x); 6 }
主函数:函数
1 package Example14; 2 3 public class Demo { 4 5 public static void main(String[] args) { 6 China zhang; 7 Japan henlu; 8 zhang = new China(); 9 henlu = new Japan(); 10 zhang.number = 32 + Computable.MAX; 11 henlu.number = 14 + Computable.MAX; 12 System.out.println("zhang的学号" + zhang.number + " zhang求和结果" + zhang.f(100)); 13 System.out.println("henlu的学号" + henlu.number + " henlu求和结果" + henlu.f(100)); 14 } 15 16 }
运行结果:spa
zhang的学号78 zhang求和结果5050
henlu的学号60 henlu求和结果146设计
例子2:
动机类MotorVehicles :指针
1 package Example15; 2 3 interface MoneyFare { 4 void charge(); 5 }
空调接口ControlTemperature:调试
1 package Example15; 2 3 interface ControlTemperature { 4 void controlAirTemperature(); 5 }
Bus类继承了动机类而且实现了收费接口code
1 package Example15; 2 //bus实现MoneyFare 3 //一个接口 4 5 public class Bus extends MotorVehicles implements MoneyFare{ 6 7 void brake(){ 8 System.out.println("公共汽车使用毂式刹车"); 9 }//重写 10 11 public void charge() { 12 System.out.println("公共汽车:一元/张,不计算千米数"); 13 } 14 15 16 }
Taxi类继承了动机类而且实现了空调和收费接口对象
1 package Example15; 2 3 public class Taxi extends MotorVehicles implements MoneyFare ,ControlTemperature { 4 5 6 public void charge() { 7 System.out.println("出租车:2元/千米,起价3千米"); 8 } 9 10 11 void brake() { 12 System.out.println("出租车使用盘式刹车技术:"); 13 } 14 15 16 public void controlAirTemperature() { 17 System.out.println("出租车安装了Hair空调"); 18 } 19 20 }
Cinrma 实现了空调和收费接口
1 package Example15; 2 3 public class Cinrma implements MoneyFare, ControlTemperature { 4 5 @Override 6 public void controlAirTemperature() { 7 System.out.println("电影院安装了中央空调"); 8 } 9 10 @Override 11 public void charge() { 12 System.out.println("电影院:门票,10/张"); 13 } 14 15 }
主函数调用
1 package Example15; 2 3 public class Demo { 4 5 public static void main(String[] args) { 6 Bus bus = new Bus(); 7 Taxi taxi = new Taxi(); 8 Cinrma cinrma = new Cinrma(); 9 bus.brake(); 10 bus.charge(); 11 taxi.charge(); 12 taxi.brake(); 13 taxi.controlAirTemperature(); 14 cinrma.charge(); 15 cinrma.controlAirTemperature(); 16 } 17 18 }
调试结果:
公共汽车使用毂式刹车 公共汽车:一元/张,不计算千米数 出租车:2元/千米,起价3千米 出租车使用盘式刹车技术: 出租车安装了Hair空调 电影院:门票,10/张 电影院安装了中央空调
关于接口回调
和类同样,接口也是Java中一种重要的数据类型,用接口声明的变量称做接口变量。
接口属于引用型变量,接口变量中能够存放实现该接口类的实例应引用,即存放对象的引用。
“接口回调”这个词是借用了C语言中的指针回调的术语,表示一个变量的地址在某一个时刻放在一个指针变量中,那么指针变量就能够间接操做该变量中存放的数据。
在Java语言中,接口回调是指:能够把实现某一接口的类建立的对象的引用赋值给该接口声明的接口变量,那么该接口变量就能够调用被类实现的接口方法。事实上,当接口变量调用被类实现的接口方法时,就是通知相应的对象调用这个方法。
举个例子:假设Com是一个接口,ImpleCom类是实现Com接口的类
Com com; ImpleCom impleCom; com = impleCom;// 这样是合法的。将impleCom 的对象的引用赋值给com接口。
相似上转型对象调用子类重写的方法
下面咱们举个例子:
ShowMessage 接口:
package Example16; public interface ShowMessage { void 显示商标(String s); }
PC类实现了ShowMessage接口
package Example16; public class PC implements ShowMessage { public void 显示商标(String s) { System.out.println(s); } }
TV类实现了ShowMessage 接口:
package Example16; public class TV implements ShowMessage { public void 显示商标(String s) { System.out.println(s); } }
主函数:
package Example16; public class Demo { public static void main(String[] args) { ShowMessage message; message = new TV(); message.显示商标("长虹牌电视机"); message = new PC(); message.显示商标("华硕A550jk4200"); } }
调试结果
长虹牌电视机 华硕A550jk4200
关于接口和多态:
接口产生的多态就是指不一样的类在实现同一个接口时可能具备不一样的实现方法,那么接口变量在回调接口方法是就可能具备多种形态。
下面咱们举个例子:
接口ComputerAverage :
package Example17; interface ComputerAverage { public double average(double a,double b); }
类A实现接口ComputerAverage
package Example17; public class A implements ComputerAverage { public double average(double a, double b) { double aver = 0; aver = (a+b)/2; return aver; } }
类B实现接口ComputerAverage
package Example17; public class B implements ComputerAverage { public double average(double a, double b) { double aver = 0; aver = Math.sqrt(a*b); return aver; } }
主函数调用:
package Example17; public class Demo { public static void main(String[] args) { ComputerAverage average; double a = 11.45,b = 45.45; average = new A(); double result = average.average(a, b); System.out.println(a + "和" + b + "的算术平均值:" + result ); average = new B(); result = average.average(a, b); System.out.println(a + "和" + b + "的几何平均值:" + result ); } }
调试结果:
11.45和45.45的算术平均值:28.450000000000003 11.45和45.45的几个平均值:22.81233219116362
在这个例子中类A和类B都实现了ComputerAverage接口,可是实现的方式不一样。
关于接口参数:
若是一个方法参数的类型是接口类型,咱们就能够将任何实现该接口的类的实例的引用传递给接口参数,那么接口参数就能够回调类实现的接口方法,下面举个例子:
基本接口SpeakHello.java
package Example18; interface SpeakHello { void speakHello(); }
Chinese类实现接口:
package Example18; public class Chinese implements SpeakHello { public void speakHello() { System.out.println("中国人习惯问候语:你好!吃饭了吗?"); } }
English类实现接口
package Example18; public class English implements SpeakHello { public void speakHello() { System.out.println("英国人习惯性用语:你好,天气不错!"); } }
KindHello类使用接口类型参数,实现接口回调
package Example18; public class KindHello { public void lookHello(SpeakHello hello) { //接口类型参数,接口回调 hello.speakHello(); } }
主调用函数:
1 package Example18; 2 3 public class Demo { 4 5 public static void main(String[] args) { 6 KindHello kindHello = new KindHello(); 7 kindHello.lookHello(new Chinese()); 8 kindHello.lookHello(new English()); 9 } 10 11 }
调试结果:
1 中国人习惯问候语:你好!吃饭了吗? 2 英国人习惯性用语:你好,天气不错!
abstract类与接口的比较:
一、abstract类和接口均可以有abstract方法。
二、接口中只能够有常量,不能有变量;而abstract类中既能够有常量也能够有变量。
三、abstract类中也能够有非abstract方法,而接口必须是抽象方法。
须要注意的是:
在设计程序时应当根据具体的方法来肯定是使用抽象类仍是接口。abstract类除了提供重要的须要子类重写的abstract方法以外,也提供了子类能够继承的变量和非abstract方法。若是某个问题须要使用继承才能更好地解决,好比:子类除了须要重写父类的abstract方法,还须要从父类继承一些变量或者继承一些重要的非abstract方法,就能够考虑使用abstract类。若是某个问题不须要继承,只是须要若干个子类给出某些重要的abstract方法的实现细节,就能够考虑使用接口。
一个面向接口编程的应用举例:
问题的提出:
设计一个广告牌,但愿所设计的广告牌能够展现许多公司的广告词。
一、问题的分析:
若是咱们设计的建立广告牌的类中是某个具体公司类。(例如联想公司类),声明了对象。那么咱们的广告牌就缺乏弹性,由于用户一旦须要广告牌展现其余公司的广告词,就须要修改广告牌类的代码,好比用长虹公司声明成员变量。
若是没当用户有了新的需求,就会致使修改类的某部分代码,那么就应当将这部分代码从该类重分割出去,使它和其余稳定的代码之间是松耦合的关系(不然系统缺少弹性,难以维护),即将每种可能的变化对应地交给实现接口的类(抽象类的子类)去负责完成。
二、设计接口。
根据以上的对问题的分析,首先设计一个接口Advertisement,改接口有2个方法show-Advertisement()和getCorpName();那么实现Advertisement接口的类必须重写,show-Advertisement()和getCropName()方法,及要求各个公司给出具体的广告词和公司的名称。
三、设计广告牌类
而后咱们设计AdvertisementBoard类(广告牌),该类有一个show(Advertisement adver)方法,该方法的参数adver是Advertisement接口类型(就像人们常说的,广告牌对外留有接口)。显然,该及参数adver能够存听任何实现Advertisement接口的类的对象的引用,而且回调重写的接口方法ShowAdvertisement()来显示公司的广告词,回调类重写的接口方法getCropName()来显示公司的名称。
下面是具体实现的代码:
广告Advertisement接口:
1 package Example19; 2 /** 3 * 接口 4 * @author 10497 5 * 6 */ 7 public interface Advertisement { 8 public void ShowAdvertisement(); 9 public String getCropName(); 10 }
广告牌类,完成接口回调:
1 package Example19; 2 /** 3 * 广告牌类 4 * @author 10497 5 * 6 */ 7 8 public class AdvertisementBoard { 9 public void Show(Advertisement adver){//使用接口参数 10 System.out.println(adver.getCropName() + "的广告词以下:"); 11 adver.ShowAdvertisement(); 12 //接口回调 13 } 14 }
安踏公司实现接口:
1 package Example19; 2 3 public class AnTaCrop implements Advertisement { 4 5 public void ShowAdvertisement() { 6 System.out.println("@@@@@@@@@@@@@@@@@@@"); 7 System.out.println("安踏,运动永不止步~~"); 8 System.out.println("@@@@@@@@@@@@@@@@@@@"); 9 } 10 11 public String getCropName() { 12 return "安踏有限公司"; 13 } 14 15 }
特步公司实现接口
package Example19; public class TeBuCorp implements Advertisement { public void ShowAdvertisement() { System.out.println("**********************"); System.out.println("特步,非通常的感受~~~~~"); System.out.println("**********************"); } public String getCropName() { return "特步有限公司"; } }
主调用函数:
1 package Example19; 2 3 public class Application { 4 public static void main(String args[]){ 5 AdvertisementBoard board = new AdvertisementBoard(); 6 board.Show(new AnTaCrop()); 7 board.Show(new TeBuCorp()); 8 } 9 }
调试结果:
1 安踏有限公司的广告词以下: 2 @@@@@@@@@@@@@@@@@@@ 3 安踏,运动永不止步~~ 4 @@@@@@@@@@@@@@@@@@@ 5 特步有限公司的广告词以下: 6 ********************** 7 特步,非通常的感受~~~~~ 8 **********************