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