Sung in Blog

                     一些技術(shù)文章 & 一些生活雜碎

          好的面向?qū)ο缶幊桃箢愒O(shè)計(jì)人員隱藏那些不需要類的使用人員了解的信息。對于 Java 編程語言,這樣的訪問可以通過使用關(guān)鍵字 private, protected, 和 public來控制。這些關(guān)鍵字控制類內(nèi)部的變量和方法是否可見,但是不好的類設(shè)計(jì)導(dǎo)致太多的可見信息和方法沒有被很好的封裝。

          ??? 封裝的一種方式是通過使用接口(Interface)實(shí)現(xiàn)的。接口提供一種途徑,使類隱藏其處理的特定事物的細(xì)節(jié),僅對外公布它必須支持的屬性。對于編程所涉及的,你可以修改類的實(shí)現(xiàn),而不修改它的調(diào)用,因?yàn)閷傩员旧頉]有改變,修改的僅僅是類的實(shí)現(xiàn)。

          ??? 一個接口被經(jīng)常用得到的地方是Collection Framework。這個框架定義了一組非常重要的接口,它們是由一組多個類實(shí)現(xiàn)的。通過僅僅研究主要的接口,你可以有效的掌握整個框架,因?yàn)樘貏e的實(shí)現(xiàn)類一般不影響設(shè)計(jì)的整體。

          ??? 例如,List接口定義了一個有序的元素集合??捎玫貙?shí)現(xiàn)包括ArrayList和LinkedList,它們都實(shí)現(xiàn)了List接口。當(dāng)你的程序需要處理List時,不必考慮它是ArrayList還是LinkedList,只要知道所選用的類的屬性即可。這個屬性就是接口。

          ??? 通過實(shí)現(xiàn)類的接口,并且在類設(shè)計(jì)時僅對外公布接口,你就有效的封裝了類的定義,這樣后臺實(shí)現(xiàn)的變動將對系統(tǒng)其它部分的影響最小。

          ??? 以ArrayList和LinkedList為例。將ArrayList看作一個可增長的數(shù)組對象(指是存儲對象,而不是原始數(shù)據(jù))。當(dāng)類實(shí)現(xiàn)了List的全部接口時,它的特性在特定條件下是可以優(yōu)化的。

          ??? 例如,如果你的程序是要隊(duì)列表中的數(shù)據(jù)進(jìn)行頻繁的隨機(jī)訪問,(例如,顯示第3,12,2,和25項(xiàng)數(shù)據(jù))ArrayList類提供對列表中每一個數(shù)據(jù)快速查詢??焖俨樵兪且栽诹斜碇虚g添加和刪除數(shù)據(jù)的速度為代價的。如果后一種行為是你需要的,那么LinkedList類是一個好的選擇。它提供快速的順序訪問、添加和刪除,但是,代價是慢速隨機(jī)查詢。

          ??? 在處理ArrayList和LinkedList時,有兩種方式創(chuàng)建對象:

          ??? List cityList = new ArrayList() ;

          ??? LinkedList peopleList = new LinkedList() ;

          ??? 兩個代碼段都是正確的,但是這兩行代碼之間存在的顯著的差別。第一行表示我們要創(chuàng)建一個ArrayList,但是我們只需要把它作為一個List來訪問。第二行正好相反。是,LinkedList項(xiàng)目被創(chuàng)建了,ArrayList也一樣。但是,聲明部分說明它只能作為LinkedList來訪問,這就數(shù)它的最大區(qū)別。

          ??? 理解接口真正變的重要是在這兩行代碼的用戶確定“查詢項(xiàng)目n”比在位置m處刪除(或添加)項(xiàng)目更為重要時。

          ??? PeopleList變量被聲明為LinkedList類型。這不是它本身的問題,因?yàn)槟阊芯康母顚哟蔚膬?nèi)容,你將發(fā)現(xiàn)peopleList在任何地方都被作為LinkedList對象處理。在你對peopleList使用LinkedList特有的方法的同時,如果你想把它作為ArrayList來處理,將會出現(xiàn)問題。

          ??? List peopleList = new ArrayList() ;

          ??? 通過學(xué)習(xí)僅使用接口來處理任何對象,你將發(fā)現(xiàn)在設(shè)計(jì)完成之后修改實(shí)現(xiàn),你需要修改的僅僅是聲明部分,除此之外,沒有任何代碼改動。這就是接口的絕妙之處。因?yàn)轭惖淖畛趼暶魇荓inkedList,當(dāng)類型變?yōu)長ist時意味著象addFirst或addLast這樣的方法是無效的,因?yàn)樾碌膒eopleList的類型是List,它沒有這些方法。

          ??? 這種基于接口設(shè)計(jì)的代碼,就像Collection Framework所向大家承諾的那樣,任何人編寫的代碼是以循環(huán)構(gòu)造方式進(jìn)行的,而無需知道使用的是哪個Collection。創(chuàng)建的類是被限制為提供接口的完全實(shí)現(xiàn)。除此之外,新代碼將不能被編譯。

          ??? 作為實(shí)例,下面的程序創(chuàng)建一組集合。每個集合提供一個系統(tǒng)定義的Iterator這樣集合的每個元素可以被訪問。這個iterator將被傳遞到幫助例程,在這里集合的獨(dú)立元素將被打印。

          ? import java.util.*;

          ? public class Interfaces {

          public static void main(String args[]) {
          Properties props = System.getProperties();
          Set keySet = props.keySet();
          dumpIterator(keySet.iterator());

          List list = Arrays.asList(args);
          dumpIterator(list.iterator());
          }

          private static void dumpIterator(Iterator itor) {
          // System.out.println(itor.getClass().getName());
          while (itor.hasNext()) {
          System.out.println(">> " + itor.next());
          }
          System.out.println("----");
          }
          ? }

          ??? 類Iterator的類型是unknown,這正是接口的絕妙之處,而不是問題。真正的事實(shí)是iterator方法返回的是一個真實(shí)的Iterator對象。然而,dumpIterator通常提供接口的完全實(shí)現(xiàn)。

          ??? 如果你去掉dumpIterator中的println行的注釋,你將發(fā)現(xiàn)真實(shí)的iterator類名,對Properties是Hashtable.Enumerator而List是AbstractList.Itr。這個事實(shí)不必知道,也不會對你的程序有任何幫助。真正重要的是List和Properties的iterator方法所返回的任何對象,必須實(shí)現(xiàn)java.util.Iterator:hasNext, next和remove方法。沒有這三種方法中任何兩種,dumpIterator方法將永遠(yuǎn)不能工作。

          posted on 2005-09-19 22:14 Sung 閱讀(127) 評論(0)  編輯  收藏 所屬分類: Java
          主站蜘蛛池模板: 浠水县| 米林县| 江达县| 边坝县| 河曲县| 洮南市| 土默特右旗| 永平县| 大竹县| 尉犁县| 曲水县| 澄江县| 丹巴县| 蓬莱市| 双城市| 报价| 会东县| 宁国市| 穆棱市| 双柏县| 铁力市| 万源市| 庆云县| 丰原市| 武冈市| 乐都县| 友谊县| 仪陇县| 陇西县| 克什克腾旗| 龙州县| 崇信县| 塘沽区| 玉环县| 松阳县| 沭阳县| 新乐市| 石嘴山市| 中宁县| 汉川市| 鱼台县|