在JAVA里說(shuō)接口,有兩個(gè)意思。廣義的意思:一個(gè) 類(lèi)/軟件實(shí)體 對(duì)外提供的方法的集合,而狹義的意思就是關(guān)鍵字 interface 所代表的JAVA里特有的一種概念。如果您看到這里就明白了,那可以不用往下看了,我不想班門(mén)弄斧!
何為“對(duì)外提供的方法的集合”?第一次看到這個(gè)廉潔時(shí)我也很納悶,不急!如果你有一些軟件工程的知識(shí),那么下面的這些你一定不會(huì)陌生:一個(gè)軟件實(shí)體應(yīng)盡可能滴做到“高內(nèi)聚,低耦合”!而做到低耦合的一個(gè)方法就是向外界提供一個(gè)窄接口!OK!終于出現(xiàn)了“接口”二字。這個(gè)概念在軟件工程中,也就是要比JAVA還早一些就有了的東西,好了,先解釋清楚了它不是JAVA的“特產(chǎn)”!
鑒于我對(duì)其它對(duì)象語(yǔ)言的完全無(wú)知,在此還是以JAVA說(shuō)法。 在JAVA里有四個(gè)訪問(wèn)權(quán)限,分別由三個(gè)訪問(wèn)修飾符和一個(gè)缺省修飾符確定。一般而言,一個(gè)類(lèi)的成員變量都被用 private 修飾,而成員方法的修飾符多看設(shè)計(jì)者的意圖了( static 修改的是類(lèi)××,而不是成員××,一般都是用 public 修飾)。那么我下面的這個(gè)說(shuō)法應(yīng)該是沒(méi)有問(wèn)題的: private 是不向外提供的, protected 修飾的方法是對(duì)子類(lèi)提供的訪問(wèn)接口,不加修飾符的方法是對(duì)本包中其它類(lèi)提供的訪問(wèn)接口,而 public 修飾符的方法是對(duì)所有類(lèi)提供的訪問(wèn)接口。 我想要是我的表達(dá)不是太次的話,那就把接口的第一個(gè)意思描述清楚了。且慢,我再多嘴兩句。 看別人的代碼總是那么容易,但當(dāng)你自己寫(xiě)東西的時(shí)候一定要注意了,應(yīng)該盡量少用 public 來(lái)修飾你寫(xiě)的方法!能不用就不能,可以用 private 的時(shí)候就要堅(jiān)決用它!舉一個(gè)很簡(jiǎn)單的例子。在開(kāi)發(fā)初期,你對(duì)此沒(méi)什么概念,生怕哪個(gè)方法別的類(lèi)用不到,狂用 public ,等開(kāi)發(fā)基本結(jié)束開(kāi)始復(fù)審時(shí),麻煩來(lái)了,你發(fā)現(xiàn)某一個(gè)工具類(lèi)的一些方法不應(yīng)該公開(kāi),但一開(kāi)始時(shí)公開(kāi)了,導(dǎo)致了一系列的地方對(duì)它引用了,試問(wèn),此時(shí)的你會(huì)選擇哪條路呢?把引用的地方一個(gè)個(gè)地改過(guò)來(lái),還是讓這個(gè)惡性腫瘤繼續(xù)擴(kuò)大?有一句老話是沒(méi)錯(cuò)滴:病是早醫(yī)好!如果當(dāng)初你就把牢給補(bǔ)上,那今天就不會(huì)有那么多的狼來(lái)偷你的羊了!
好了,現(xiàn)在說(shuō) interface 。
如果你的記性不差,那想想你看JAVA書(shū)時(shí)他是怎么說(shuō)的。為了克服多重繼承帶來(lái)的麻煩,JAVA取消了C++里的多繼承,而用接口來(lái)代替。接口沒(méi)有消除多繼承的好處但去掉了多繼承帶來(lái)的壞處!似乎很神奇哦,但,別被它嚇到了。
先看這一些代碼:
可以看到,只是簡(jiǎn)單滴把 extends 改寫(xiě)成 implements 就是了。而客戶端的代碼是完全一樣的。當(dāng)然,運(yùn)行的效果也是一樣的。 說(shuō)到這里,我想您大概會(huì)覺(jué)得好膚淺,其實(shí),我想要的效果也就差不多是這樣了。
如果你覺(jué)得不夠過(guò)癮,沒(méi)事,理解了就最好。這里還有個(gè)例子。我將向你展示接口的另一種理解方法。 假設(shè)我們要實(shí)現(xiàn)一個(gè)從 1 加到 N 的程序,你會(huì)說(shuō), it's so easy. 于是
其實(shí)他給的你什么代碼你并不會(huì)關(guān)心,你只是知道了,我要的功能有了,這就好了。接口,這就是它給你帶來(lái)的好處。 那么,從這里,你是不是體會(huì)到了另一種理解接口的思路呢?
接口,可以把它說(shuō)成是一個(gè)協(xié)議,意思即:你要用我的東西,你就必須遵守我的規(guī)定!像上面那樣,B 要使用接口 Sum 的功能,他只有一個(gè)方法來(lái)調(diào)用它:
Sum s = new SumImp1(); int sum = s.sum(1, 100); s = new SumImp2(); sum = s.sum(1, 100);
接口的好處就在這里體現(xiàn)出來(lái)了。s 只是一個(gè)引用,它的靜態(tài)類(lèi)型是 Sum ,而動(dòng)態(tài)類(lèi)型則可以被你支配!在這里,你可以調(diào)用 SumImp1 ,也可以用 SumImp2 ,隨你的高興就是了。但 s.xxx(),這里的 xxx() 一定是在 Sum 里定義的,而在 SumImp1 或者 SumImp2 里定義的其它一切對(duì)于 s 來(lái)說(shuō)都是不可見(jiàn)的。所以,用接口可以很好地限制與外部的耦合,而且基本上是一勞永逸的做法,一開(kāi)始定義好一個(gè)接口,以后沒(méi)有了一點(diǎn)擔(dān)心的必要!
到這里,我算是說(shuō)完了,朋友,你要是覺(jué)得我說(shuō)得不差,那記住就行了。但如果你覺(jué)得沒(méi)明白,可以留言,我盡全力把我知道的都說(shuō)出來(lái),但愿我理解的不是錯(cuò)的。 如果你覺(jué)得我哪里說(shuō)錯(cuò)了,那請(qǐng)您把我錯(cuò)在哪里指出來(lái),相互討論自己的所好,于我而言,實(shí)在是人生一大樂(lè)事矣!