---恢復內容開始---
轉載自:http://www.cnblogs.com/aisiteru/articles/1151874.html
第一次看這篇文章時,是在CSDN博客中看到的,作者寫的初衷還是蠻好的,但是確實有錯誤的地方和不是很明
白的地方。於是就很想去看看原文,廢了半天的功夫終於找到了,原文還是一樣有出錯和我不理解的地方,我也把原
文的地址貼在上面了。三月份學習的Java集合框架這部分,這幾天拿出來整理就想再深入一點,因此也看了很多的關
於Java集合框架的文章,這篇我算是有一點點的體會,我只是改了一些我認為錯誤的地方和不通順的地方。
改過的原文:
List是一個接口,而ArrayList是List接口的一個實現類。
ArrayList類繼承並實現了List接口。
因此,List接口不能被構造,也就是我們說的不能創建實例對象,但是我們可以像下面那樣為List接口創建一個指
向自己的對象引用,而ArrayList實現類的實例對象就在這充當了這個指向List接口的對象引用。
個人見解:
要是你已經學過了OOP,上面的部分是不難理解的,這是面向對象重要的知識點,面向對象最重要的就是多態,
我們都知道接口和抽象不能被實例化,但是它們可以創建一個指向自己的對象引用,它們的實現類或子類就在充當這
樣的角色,我想這就是面向對象編程中多態的優勢。前些日子在學習UML建模語言和Java設計模式的時候,深深地的
體會到了面向對象編程的好處,Java集合框架中用到也不足為奇,Java本身就是面向對象的編程語言。
上面的理解可能有點難度,但是我們找一個具體的實例,就會理解起來比較容易。我們定義一個動物的抽象類
Animal,再定義一個繼承自Animal基類的Dog類,看下面的代碼就會理解抽象類和接口不能被實例化:
- <span style="font-size:18px;">public class Test{
- public static void main(String[] args){
- Animal a1 = new Animal();//編譯出錯
- Animal a2 = new Dog();
- }
- }
- abstract class Animal{
- //動物名字
- String name;
- //動物叫聲
- public void shout(){
- System.out.println("叫聲...");
- }
- }
- class Dog extends Animal{
- //狗類獨有的方法
- public void guard(){
- System.out.println("狗有看門的獨特本領!");
- }
- }</span>
編譯結果:
List list;//正確,list = null;
List list = new List();//是錯誤的用法
List list = new ArrayList();這句創建了一個ArrayList實現類的對象后把它上溯到了List接口。此時它就是一個List對
象了,它有些ArrayList類具有的,但是List接口沒有的屬性和方法,它就不能再用了。 而ArrayList list=newArrayList();
創建一對象則保留了ArrayList的所有屬性和方法。
個人見解
我們繼續上面的例子,如果我們創建的是抽象類的對象引用,那么這個對象只能調用自己的非抽象方法,下面的
是shout()方法,不能調用繼承它的子類的獨有的方法,在下面的就是guard()方法不能被a1調用,繼續測試代碼:
- <span style="font-size:18px;">public class Test{
- public static void main(String[] args){
- Animal a1 = new Dog();
- a1.shout();//編譯通過
- //a1.guard();//編譯出錯
- }
- }
- abstract class Animal{
- //動物名字
- String name;
- //動物叫聲
- public void shout(){
- System.out.println("叫聲...");
- }
- }
- class Dog extends Animal{
- //狗類獨有的方法
- public void guard(){
- System.out.println("狗有看門的獨特本領!");
- }
- }
- </span>
編譯結果:
如果我們采用Dog d1 = new Dog();那么d1可以調用抽象類和子類的所有屬性和方法,這里不再測試。
這是一個例子:
- <span style="font-size:18px;">import java.util.*;
- public class Demo{
- public static void main(String[] args){
- List list = new ArrayList();
- ArrayList arrayList = new ArrayList();
- list.trimToSize();//錯誤,沒有該方法。
- arrayList.trimToSize();//ArrayList里有該方法。
- }
- }</span>
編譯一下就知道結果了。
個人見解
我剛在前面的文章里面把Java API中List接口和ArrayList實現類的方法都列出來了,可以看到List接口中並沒有
trimToSize()方法,但這個方法在它的實現類ArrayList中有。因此編譯的結果為:
如果是下面這個樣子的:
List a=new ArrayList();
則a擁有List的所有屬性和方法,不會擁有其實現類ArrayList的獨有的屬性和方法。
如果List與ArrayList中有相同的屬性(如int i),有相同的方法(如void f()),
則a.i是調用了List中的i
a.f()是調用了ArrayList中的f();
----------------------------------------------------------------------------------------------------------------
問題的關鍵:
為什么要用 List list = new ArrayList() ,而不用 ArrayList alist = new ArrayList()呢?
問題就在於List接口有多個實現類,現在你用的是ArrayList,也許哪一天你需要換成其它的實現類,如
LinkedList或者Vector等等,這時你只要改變這一行就行了: List list = new LinkedList(); 其它使用了list地方的代碼根
本不需要改動。
假設你開始用ArrayList alist = new ArrayList(), 這下你有的改了,特別是如果你使用了ArrayList實現類特有的方法
和屬性。
個人見解
上面的說明,我是在看了設計模式才恍然大悟的,設計模式的原則和理念果然是強大的,只有好好學習了面向對
象原則和設計模式,那么理解上面的就不再是難度,這樣的好處是為了代碼的可維護性,可復用性,可擴展性以及靈
活性,再者就是這符合了里氏代換原則和開閉原則。看來學習設計模式好處是大大的。
地區用List arr = new ArrayList();定義;行業用ArrayList arr = new ArrayList();定義;則說明,行業里用到了ArrayList的
特殊的方法.
另外的例子就是,在類的方法中,如下聲明:
private void doMyAction(List list){}
這樣這個方法能處理所有實現了List接口的類,一定程度上實現了泛型函數.
如果開發的時候覺得ArrayList,HashMap的性能不能滿足你的需要,可以通過實現List,Map(或者Collection)來定制
你的自定義類.
個人見解
正因為List是接口,所以它的擴展性是良好的,這是面向對象編程最大的改變,也是它的核心,在這里我是體會
到了一句話,就是Java集合框架的學習最難體現你學習Java語言的程序都多深,看來我以前學習的程度只是停留在入
門級別了,這幾天可要好好再溫習重新認識一番Java集合框架了。
可能理解不是很深,對於原文的理解也就這些了,不對的地方自己會及時更正。
---恢復內容結束---