接口的定義和類的定義很類似,能夠分爲接口聲明和接口體積,和類不一樣的是,使用關鍵字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 **********************