久久―日本道色综合久久,亚洲欧美精品在线,狼狼色丁香久久婷婷综合五月,香蕉人人超,日本网站黄,国产在线观看不卡免费高清,无遮挡的毛片免费

2023信創(chuàng)獨角獸企業(yè)100強
全世界各行各業(yè)聯(lián)合起來,internet一定要實現(xiàn)!

深入理解AbstractClass和interface

2004-02-15 eNet&Ciweek

  考慮這樣一個例子,假設(shè)在我們的問題領(lǐng)域中有一個關(guān)于Door的抽象概念,該Door具有執(zhí)行兩個動作open和close,此時我們可以通過abstract class或者interface來定義一個表示該抽象概念的類型,定義方式分別如下所示:

  使用abstract class方式定義Door:
  abstract class Door {
   abstract void open();
   abstract void close();
  }

  使用interface方式定義Door:

  interface Door {
   void open();
   void close();
  }   

  其他具體的Door類型可以extends使用abstract class方式定義的Door或者implements使用interface方式定義的Door??雌饋砗孟袷褂胊bstract class和interface沒有大的區(qū)別?! ?

  如果現(xiàn)在要求Door還要具有報警的功能。我們該如何設(shè)計針對該例子的類結(jié)構(gòu)呢(在本例中,主要是為了展示abstract class和interface反映在設(shè)計理念上的區(qū)別,其他方面無關(guān)的問題都做了簡化或者忽略)?下面將羅列出可能的解決方案,并從設(shè)計理念層面對這些不同的方案進行分析?! ?

  解決方案一:  

  簡單的在Door的定義中增加一個alarm方法,如下:
  abstract class Door {
   abstract void open();
   abstract void close();
   abstract void alarm();
  }

  或者

  interface Door {
   void open();
   void close();
   void alarm();
  }   

  那么具有報警功能的AlarmDoor的定義方式如下: 

  class AlarmDoor extends Door {
   void open() { … }
   void close() { … }
   void alarm() { … }
  }   

  或者  

  class AlarmDoor implements Door {
   void open() { … }
   void close() { … }
   void alarm() { … }
 ?。?

  這種方法違反了面向?qū)ο笤O(shè)計中的一個核心原則ISP(Interface Segregation Priciple),在Door的定義中把Door概念本身固有的行為方法和另外一個概念"報警器"的行為方法混在了一起。這樣引起的一個問題是那些僅僅依賴于Door這個概念的模塊會因為"報警器"這個概念的改變(比如:修改alarm方法的參數(shù))而改變,反之依然?! ?

  解決方案二:  

  既然open、close和alarm屬于兩個不同的概念,根據(jù)ISP原則應(yīng)該把它們分別定義在代表這兩個概念的抽象類中。定義方式有:這兩個概念都使用abstract class方式定義;兩個概念都使用interface方式定義;一個概念使用abstract class方式定義,另一個概念使用interface方式定義?! ?

  顯然,由于Java語言不支持多重繼承,所以兩個概念都使用abstract class方式定義是不可行的。后面兩種方式都是可行的,但是對于它們的選擇卻反映出對于問題領(lǐng)域中的概念本質(zhì)的理解、對于設(shè)計意圖的反映是否正確、合理。我們一一來分析、說明。   

  如果兩個概念都使用interface方式來定義,那么就反映出兩個問題:1、我們可能沒有理解清楚問題領(lǐng)域,AlarmDoor在概念本質(zhì)上到底是Door還是報警器?2、如果我們對于問題領(lǐng)域的理解沒有問題,比如:我們通過對于問題領(lǐng)域的分析發(fā)現(xiàn)AlarmDoor在概念本質(zhì)上和Door是一致的,那么我們在實現(xiàn)時就沒有能夠正確的揭示我們的設(shè)計意圖,因為在這兩個概念的定義上(均使用interface方式定義)反映不出上述含義。

  如果我們對于問題領(lǐng)域的理解是:AlarmDoor在概念本質(zhì)上是Door,同時它有具有報警的功能。我們該如何來設(shè)計、實現(xiàn)來明確的反映出我們的意思呢?前面已經(jīng)說過,abstract class在Java語言中表示一種繼承關(guān)系,而繼承關(guān)系在本質(zhì)上是"is a"關(guān)系。所以對于Door這個概念,我們應(yīng)該使用abstarct class方式來定義。另外,AlarmDoor又具有報警功能,說明它又能夠完成報警概念中定義的行為,所以報警概念可以通過interface方式定義。如下所示:  

  abstract class Door {
   abstract void open();
   abstract void close();
  }
  interface Alarm {
   void alarm();
  }

  class AlarmDoor extends Door implements Alarm {
   void open() { … }
   void close() { … }
   void alarm() { … }
  }   

  這種實現(xiàn)方式基本上能夠明確的反映出我們對于問題領(lǐng)域的理解,正確的揭示我們的設(shè)計意圖。其實abstract class表示的是"is a"關(guān)系,interface表示的是"like a"關(guān)系,大家在選擇時可以作為一個依據(jù),當(dāng)然這是建立在對問題領(lǐng)域的理解上的,比如:如果我們認為AlarmDoor在概念本質(zhì)上是報警器,同時又具有Door的功能,那么上述的定義方式就要反過來了?! ?

  結(jié)論  

  abstract class和interface是Java語言中的兩種定義抽象類的方式,它們之間有很大的相似性。但是對于它們的選擇卻又往往反映出對于問題領(lǐng)域中的概念本質(zhì)的理解、對于設(shè)計意圖的反映是否正確、合理,因為它們表現(xiàn)了概念間的不同的關(guān)系(雖然都能夠?qū)崿F(xiàn)需求的功能)。這其實也是語言的一種的慣用法,希望讀者朋友能夠細細體會。

相關(guān)頻道: eNews

您對本文或本站有任何意見,請在下方提交,謝謝!

投稿信箱:tougao@enet16.com