接口(英文:Interface)是Java中非常重要的內容,初學的時候可能感受不深,但是在做項目的時候,對面向接口編程的運用就變得尤爲重要,不過這是後話了。現在先討論假如是剛剛接觸接口這個概念,該怎麼玩?如果是看過我之前文章的朋友應該瞭解,在遇到一個新概念的時候,我一般思考框架是先問下面三個問題:
1.這個東西有什麼用?用來幹什麼的?它的意義在哪裏?(顯然,如果是沒用的東西,就沒必要浪費時間了;其實,弄懂了這個問題,就掌握了50%)
2.這個概念或者技能點怎麼用?也就是它的表現形式,如關鍵字、修飾詞、語法什麼的。。。(這個佔20%)
3.這個東西在用的過程中,有哪些關鍵點和細節點?(這個佔30%)
上面三個問題搞清楚了,剩下的就是去用了。。。“無他,但手熟爾。”
一、接口有什麼用?它的意義在哪裏?
回答這個問題,兩句話就夠了:
1.接口表示一種能力;
2.接口表示一種約定。
先來看第一點“接口表示一種能力”,舉個栗子:
需求:現在要創造一個蜘蛛俠。人有“唱歌”和“考試”的功能,蜘蛛有“爬行”和“吐絲”的功能。
分析:首先蜘蛛俠是一個人,他有蜘蛛的能力。按照面向對象思想,可以將人和蜘蛛分別定義成抽象類。但是,不能讓蜘蛛俠在繼承人的同時又繼承蜘蛛。兩個原因:一、蜘蛛俠不是蜘蛛,不符合繼承中 【is a】的關係;二、Java只支持單繼承。如何解決這個問題呢?這時就要用到接口,接口是【has a】的關係。可以將蜘蛛的行爲能力定義爲接口,讓蜘蛛俠繼承人,實現蜘蛛的行爲能力的接口。實現代碼如下:
1 public abstract class Person { //定義Person抽象類 2 public abstract void sing(); //唱歌抽象方法 3 public abstract void exam(); //考試抽象方法 4 } 5 public interface ISpiderable { //定義一個蜘蛛的行爲能力接口 6 public abstract void creep(); //爬行抽象方法 7 public abstract void shootWeb(); //吐絲抽象方法 8 } 9 public class SpiderMan extends Person implements ISpiderable{//繼承人,實現蜘蛛的行爲能力接口10 String name = "彼得·帕克";11 12 @Override13 public void creep() { //實現爬行方法14 System.out.println(name + " 在屋頂上爬,在樹枝上爬,在夕陽下的草地上爬。。。");15 }16 @Override17 public void shootWeb() { //實現吐絲方法18 System.out.println(name + " 吐絲織網抓蟲子");19 }20 @Override21 public void sing() { //實現唱歌方法22 System.out.println(name + " 往事不要再提~人生已多風雨~~");23 }24 @Override25 public void exam() { //實現考試方法26 System.out.println(name + " 上午考語文,下午考數學,明天考英語。。。");27 }28 }29 public class Test { //測試一下30 public static void main(String[] args) {31 SpiderMan spiderman = new SpiderMan();32 spiderman.creep();33 spiderman.sing();34 }35 }
運行結果如下:
接着來,有天傍晚蜘蛛俠吃飽了沒事兒閒溜達,在路邊草叢裏發現了雷神的大鐵錘,於是他有具備了閃電的能力:
1 public interface ILightningable { //定義閃電能力接口 2 public abstract void lightning(); //閃電抽象方法 3 } 4 public class SpiderMan extends Person implements ISpiderable,ILightningable{//繼承人,實現蜘蛛的行爲能力接口,實現閃電能力接口 5 String name = "彼得·帕克"; 6 7 @Override 8 public void creep() { //實現爬行方法 9 System.out.println(name + " 在屋頂上爬,在樹枝上爬,在夕陽下的草地上爬。。。");10 }11 @Override12 public void shootWeb() { //實現吐絲方法13 System.out.println(name + " 吐絲織網抓蟲子");14 }15 @Override16 public void sing() { //實現唱歌方法17 System.out.println(name + " 往事不要再提~人生已多風雨~~");18 }19 @Override20 public void exam() { //實現考試方法21 System.out.println(name + " 上午考語文,下午考數學,明天考英語。。。");22 }23 @Override24 public void lightning() {25 System.out.println(name + " 來一波閃電~"); //實現閃電方法26 }27 }28 public class Test { //測試一下29 public static void main(String[] args) {30 SpiderMan spiderman = new SpiderMan();31 spiderman.creep();32 spiderman.sing();33 spiderman.lightning();34 }35 }
運行結果如下:
通過上面的例子,“接口表示一種能力”已經算是不言而喻了,那麼,爲什麼說“接口表示一種約定”?
首先,什麼是“約定”?所謂的約定就是,這事兒就按咱哥倆說的規矩辦,誰也別出幺蛾子。舉個經典的打印機的例子:要求實現打印機的打印功能。打印機的墨盒可能是彩色的,也可能是黑白的,所用的紙張可以有多種類型,如A4、B5等,要命的是墨盒和紙張都不是打印機廠商生產的。那麼,打印機廠商如何避免自的打印機與市場上的墨盒、紙張不符呢?
分析:有效解決該問題的途徑是制定墨盒、紙張的約定或標準,然後打印機廠商按照約定對墨盒、紙張提供支持,這樣一來,無論最後使用的是廠商張三還是廠商王麻子提供的墨盒或紙張,只有符合統一的約定,打印機都可以打印。當然,“接口(Interface)”就是這樣一種約定。打印機打印功能實現如下: