【正文】
ethods is abstract. 3. With abstract scaleup and reflected the design concept of different. Actually the abstract scaleup says is is a relationship with said, was like a relationship. 4. Realize abstract classes and interface classes must realize, all of the method. Abstract classes may have not abstract methods. Interface cannot have realization method. 5. Interface definition of variable default is public, immigration, and static type to the initial value, so must realize class cannot be redefined, also can39。正是由于這兩種機制的存在,才賦予了 Java 強大的面向?qū)ο竽芰?。其實,兩者?間還是有很大的區(qū)別的,對于它們的選擇甚至反映出對于問題領(lǐng)域本質(zhì)的理解、對于設(shè)計意圖的理解是否正確、合理。 理解抽象類 abstract class 和 interface 在 Java 語言中都是用來進行抽象類(本文中的抽象類并非從 abstract class 翻譯而來,它表示的是一個抽象體,而 abstract class 為 Java 語言中用于定義抽象類的一種方法,請讀者注意區(qū)分)定義的,那么什么是抽象類,使用抽象類能為我們帶來什么好處呢? 在面向?qū)ο蟮母拍钪?,我們知道所有的對象都是通過類來描繪的,但是反過來卻不是這樣。抽象類往往用來表征我們在對問題領(lǐng)域進行分析、設(shè)計中得出的抽象概念,是對一系列看上去不同,但是本質(zhì)上相同的具體概念的抽象。正是因為抽 象的概念在問題領(lǐng)域沒有對應(yīng)的具體概念,所以用以表征抽象概念的抽象類是不能夠?qū)嵗?。我們可以?gòu)造出一個固定的一組行為的抽象描述,但是這組行為卻能夠有任意個可能的具體實現(xiàn)方式。模塊可以操作一個抽象體。熟悉 OCP 的讀者一定知道,為了能夠?qū)崿F(xiàn)面向?qū)ο笤O(shè)計的一個最核心的原則 OCP(OpenClosed Principle),抽象類是其中的關(guān)鍵所在。 在 abstract class 方式中, Demo 可以有自己的數(shù)據(jù)成員,也可以有非 abstract的成員方法,而在 interface 方式的實現(xiàn)中, Demo 只能夠有靜態(tài)的不能被修改的數(shù)據(jù)成員,所有的成員方法都是 abstract 的。 從編程的角度來看, abstract class 和 interface 都可以用來實現(xiàn) design by contract 的思想。 首先, abstract class 在 Java 語言中表示的是一種繼承關(guān)系,一個類只能使用一次繼承關(guān)系 (因為 Java 不支持多繼承 轉(zhuǎn)注 )。也許,這是 Java 語言的設(shè)計者在考慮 Java 對于多重繼承的 支持方面的一種折中考慮吧。但是在 interface的定義中,方法卻不能擁有默認行為,為了繞過這個限制,必須使用委托,但是這會增加一些復雜性,有時會造成很大的麻煩。因為如果后來想修改類的界面(一般通過 abstract class 或 interface來表示)以適應(yīng)新的情況(比如,添加新的方法或者給已用的方法中添加新的參數(shù))時,就會非常的麻煩,可能要花費 很多的時間(對于派生類很多的情況,尤為如此)。 同樣,如果不能在抽象類中定義默認行為,就會導致同樣的方法實現(xiàn)出現(xiàn)在該抽象類的每一個派生類中,違反了 one rule, one place 原則,造成代碼重復,同樣不利于以后的維護。 從設(shè)計理念層面看 abstract class 和 interface 上面主要從語法定義和編程的角度論述了 abstract class 和 interface 的區(qū) 別,這些層面的區(qū)別是比較低層次的、非本質(zhì)的 。作者認為,從這個層面進行分析才能理解二者概念的本質(zhì)所在。對于 interface 來說則不然,并不要求 interface 的實現(xiàn)者和 interface定義在概念本質(zhì)上是一致的,僅僅是實現(xiàn)了 interface 定義的契約而已。 考慮這樣一個例子,假設(shè)在我們的問題領(lǐng)域中有一個關(guān)于 Door 的抽象概念,該Door 具有執(zhí)行兩個動作 open 和 close,此時我們可以通 過 abstract class 或者 interface來定義一個表示該抽象概念的類型 ??雌饋砗孟袷褂?abstract class 和 interface沒有大的區(qū)別。我們該如何設(shè)計針對該例子的類結(jié)構(gòu)呢(在本例中,主要是為了展示 abstract class 和 interface 反映在設(shè)計理念上的區(qū)別,其他方面無關(guān)的問題都做了簡化或者忽略)?下面將羅列出可能的解決方案,并從設(shè)計理念層面對這些不同的方案進行分析。這樣引起的一個問題是那些僅僅依賴于 Door 這個概念的模塊會因為 報警器 這個概念的改變(比如:修改 alarm 方法的參數(shù))而改變,反之依然。定義方式有:這兩個概念都使用 abstract class 方式定義;兩個概念都使用 interface 方式定義;一個概念使用 abstract class 方式定義,另一個概念使用 interface 方式定義。后面兩種方式都是可行的,但是對于它們的選擇卻反映出對于問題領(lǐng)域中的概念本質(zhì)的理解、對于設(shè)計意圖的反映是否正確、合理。 如果兩個概念都使用 interface 方式來定義,那么就反映出兩個問題: 我們可能沒有理解清楚問題領(lǐng)域, AlarmDoor 在概念本質(zhì)上到底是 Door 還是報警器? 如果我們對于問題領(lǐng)域的理解沒有問題,比如 :我們通過對于問題領(lǐng)域的分析發(fā)現(xiàn)AlarmDoor 在概念本質(zhì)上和 Door 是一致的,那么我們在實現(xiàn)時就沒有能夠正確的揭示我們的設(shè)計意圖,因為在這兩個概念的定義上(均使用 interface 方式定義)反映不出上述含義。我們該如何來設(shè)計、實現(xiàn)來明確的反映出我們的意思呢?前面已經(jīng)說過,abstract class 在 Java 語言中表示一種繼承關(guān)系,而繼承關(guān)系在本質(zhì)上是 isa關(guān)系。另外, AlarmDoor又具有報警功能,說明它又能夠完成報警概念中定義的行為,所以報警概念可以通過interface 方式定義。其實 abstract class 表示的是 isa關(guān)系, interface 表示的是 likea關(guān)系,大家在選擇時可以作為一個依據(jù),當然這是建立在對問題領(lǐng)域的理解上的,比如:如果我們認為 AlarmDoor 在概念本質(zhì)上是報警器,同時又具有 Door 的功能,那么上述的定義方式就要反過來了。但是,一個類卻可以實現(xiàn)多個 interface。 3. abstract class 和 interface 所反映出的設(shè)計理念不同。 4. 實現(xiàn)抽象類和接口的類必須實現(xiàn)其中的所有方法。接口中則不能有實現(xiàn)方法。 6. 抽象類中的變量默認 是 friendly 型,其值可以在子類中重新定義,也可以重新賦值。 結(jié)論 abstract class 和 interface 是 Java 語言中的兩種定義抽象類的方式,它們之間有很大的相似性。這其實也是語言的一種的慣用法,希望讀者朋友能夠細細體會。 指導教師簽名: 年 月 日 學院審核意見 年 月 日