經(jīng)常見(jiàn)List<?> list= new ArrayList<?>
Map<?,?> map = new HashMap<?,?>
但是發(fā)現(xiàn)list只是ArrayList的接口不是它的父類(lèi) ,不是父類(lèi)引用指向子類(lèi)對(duì)象
如果是應(yīng)該是AbstractLIst ablist= new ArraryList(); 或者直接寫(xiě)為ArrayList<?> list= new ArrayList<?>
為什么要用接口引用指向?qū)崿F(xiàn)類(lèi)的對(duì)象?
這種寫(xiě)法其實(shí)Java多態(tài)的表現(xiàn)形式(一個(gè)對(duì)象在不同環(huán)境下的不同表現(xiàn)形式)
多態(tài)的定義:指允許不同類(lèi)的對(duì)象對(duì)同一消息做出響應(yīng)。即同一消息可以根據(jù)發(fā)送對(duì)象的不同而采用多種不同的行為方式。(發(fā)送消息就是函數(shù)調(diào)用)
List list;是在棧區(qū)開(kāi)辟一個(gè)空間放list引用,并沒(méi)有創(chuàng)建對(duì)象所以不知道ArrayList還是LinkedList當(dāng)你list= new ArrayList(); 就創(chuàng)建了ArrayList對(duì)象。并且把開(kāi)始創(chuàng)建的list引用指向這個(gè)對(duì)象ArrayList和LinkedList都是List的實(shí)現(xiàn)類(lèi)。
為什么一般都使用 List list = new ArrayList() ,而不用 ArrayList alist = new ArrayList()呢?
問(wèn)題就在于List有多個(gè)實(shí)現(xiàn)類(lèi),如 LinkedList或者Vector等等,現(xiàn)在你用的是ArrayList,也許哪一天你需要換成其它的實(shí)現(xiàn)類(lèi)呢?這時(shí)你只要改變這一行就行了:List list = new LinkedList(); 其它使用了list地方的代碼根本不需要改動(dòng)。假設(shè)你開(kāi)始用 ArrayList alist = new ArrayList(), 這下你有的改了,特別是如果你使用了 ArrayList特有的方法和屬性。 如果沒(méi)有特別需求的話(huà),最好使用List list = new LinkedList(); ,便于程序代碼的重構(gòu). 這就是面向接口編程的好處
注意事項(xiàng)
list只能使用ArrayList中已經(jīng)實(shí)現(xiàn)了的List接口中的方法,ArrayList中那些自己的、沒(méi)有在List接口定義的方法是不可以被訪問(wèn)到的
list.add()其實(shí)是List接口的方法
但是調(diào)用ArrayList的方法如 clone()方法是調(diào)用不到的
接口的靈活性就在于“規(guī)定一個(gè)類(lèi)必須做什么,而不管你如何做”。我們可以定義一個(gè)接口類(lèi)型的引用變量來(lái)引用實(shí)現(xiàn)接口的類(lèi)的實(shí)例,當(dāng)這個(gè)引用調(diào)用方法時(shí),它會(huì)根據(jù)實(shí)際引用的類(lèi)的實(shí)例來(lái)判斷具體調(diào)用哪個(gè)方法,這和上述的超類(lèi)對(duì)象引用訪問(wèn)子類(lèi)對(duì)象的機(jī)制相似。
//定義接口InterA interface InterA { void fun(); } //實(shí)現(xiàn)接口InterA的類(lèi)B class B implements InterA { public void fun() { System.out.println(“This is B”); } } //實(shí)現(xiàn)接口InterA的類(lèi)C class C implements InterA { public void fun() { System.out.println(“This is C”); } } class Test { public static void main(String[] args) { InterA a; a= new B(); a.fun(); a = new C(); a.fun(); } }
輸出結(jié)果為:
This is B
This is C
上例中類(lèi)B和類(lèi)C是實(shí)現(xiàn)接口InterA的兩個(gè)類(lèi),分別實(shí)現(xiàn)了接口的方法fun(),通過(guò)將類(lèi)B和類(lèi)C的實(shí)例賦給接口引用a,實(shí)現(xiàn)了方法在運(yùn)行時(shí)的動(dòng)態(tài)綁定,充分利用了“一個(gè)接口,多個(gè)方法”,展示了Java的動(dòng)態(tài)多態(tài)性。
需要注意的一點(diǎn)是:Java在利用接口變量調(diào)用其實(shí)現(xiàn)類(lèi)的對(duì)象的方法時(shí),該方法必須已經(jīng)在接口中被聲明,而且在接口的實(shí)現(xiàn)類(lèi)中該實(shí)現(xiàn)方法的類(lèi)型和參數(shù)必須與接口中所定義的精確匹配。
聯(lián)系客服