<pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

          <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

          <p id="bbfd9"></p>

          <p id="bbfd9"><cite id="bbfd9"></cite></p>

            <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

            <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
            <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
            java語言

            java的繼承與組合的區別

            時間:2025-01-29 00:53:31 偲穎 java語言 我要投稿
            • 相關推薦

            java的繼承與組合的區別

              Java是一門面向對象的編程語言,不僅吸收了C++語言的各種優點,還摒棄了C++里難以理解的多繼承、指針等概念,因此Java語言具有功能強大和簡單易用兩個特征。下面是小編精心整理的java的繼承與組合的區別,僅供參考,大家一起來看看吧。

              繼承和組合的概念

              在新類里簡單地創建原有類的對象。我們把這種方法叫作“組合”,因為新類由現有類的對象合并而成。我們只是簡單地重復利用代碼的功能,而不是采用它的形式。

              第二種方法是創建一個新類,將其作為現有類的一個“類型”。我們可以原樣采取現有類的形式,并在其中加入新代碼,同時不會對現有的類產生影響。這種魔術般的行為叫作“繼承”(Inheritance),涉及的大多數工作都是由編譯器完成的。對于面向對象的程序設計,“繼承”是最重要的基礎概念之一。對于組合和繼承這兩種方法,大多數語法和行為都是類似的(因為它們都要根據現有的類型生成新類型)。

              使用場合:

              組合:各部件之間沒什么關系,只需要組合即可。like組裝電腦,需要new CPU(),new RAM(),new Disk()……

              演示代碼如下:

              public class Computer {

              public Computer() {

              CPU cpu=new CPU();

              RAM ram=new RAM();

              Disk disk=new Disk();

              }

              }

              class CPU{ }

              class RAM{ }

              class Disk{ }

              繼承:子類需要具有父類的功能,各子類之間有所差異。like Shape類作為基類,子類有Rectangle,CirCle,Triangle……

              演示代碼如下:

              class Shape {

              public void draw() {

              System.out.println("draw a shape");

              }

              public void erase() {

              System.out.println("erase");

              }

              }

              class Square extends Shape {

              @Override

              public void draw() {

              System.out.println("draw a Square");

              }

              public static void main(String[] args) {

              Square s = new Square();

              s.draw();

              s.erase();

              }

              }

              相比于組合,繼承有以下優點:

              1、在繼承中,子類自動繼承父類的非私有成員(default類型視是否同包而定),在需要時,可選擇直接使用或重寫。

              2、在繼承中,創建子類對象時,無需創建父類對象,因為系統會自動完成;而在組合中,創建組合類的對象時,通常需要創建其所使用的所有類的對象。

              組合的優點:

              1、在組合中,組合類與調用類之間低耦合;而在繼承中子類與父類高耦合。

              2、可動態組合。

              相關資料:

              雖然繼承是OOP的一大特性,但很多時候并不推薦使用,因為它常常容易使結構復雜化,容易出錯。因此,除非我們確信使用繼承會使程序效率最高,否則,不考慮使用它。

              當Java 1.5引入注解,企業開發者對簡化EJB和其他企業產品開發抱有很大期望。可以看一看同一時期的一篇文章用EJB 3.0簡化企業Java開發。

              然而從那時起,Java企業使用注解出現一些無法預料的后果和副作用,一些甚至到今天都沒有被注意到。幸運的是,并非所有的副作用都沒有被注意到,來看一些例子,在StackOverflow標題為“Why Java Annotations?”有很多有價值的評論,“Are Annotations Bad?”這篇文章有很棒的觀點,還有“Magics Is Evil”,“Annotations…Good, Bad or Worse?”。

              java-programmer,并非所有的注解都相同:

              盡管上面許多討論都包含有價值的觀點,但并不是所有注解都是相同的。

              這里有兩類注解,區別在于他們是否在運行期影響程序。首先,說一下無害的一類,它們并不會在運行期對代碼產生任何影響;另一種是有害的一類,它們會修改運行期行為。無害的注解包括@Deprecated, @Override, @SuppressWarnings, 等等。有害的注解包括@Entity, @Table, @PostConstruct, @ApplicationScoped,等等。

              在無害的注解中存在一小部分注解,它們非常實用。有一些提供在編譯期間(靜態檢查)捕獲錯誤或提供安全保障。一些實用的注解包括:@Override, @NonNull/@Nullable 來自(Checker Framework), 等等。

              為什么有害的注解不好?我們定義了一些有害的注解,為什么要避免使用它們呢?

              想象一個標準的Java Data類擁有@PostConstruct方法。這個注解表示所標注的方法應該在對象創建好之后被調用。這個功能并不是由JVM處理,所以Date類隱式獲取未知的框架和容器,而自身語義上并沒有做任何事情。如果這些代碼并不運行在任何容器中,而只是運行在JVM中呢?這個注解大大降低了這個類的重用性。另外對于任何使用Date的地方進行單元測試就變成了噩夢,因為你必須確保每次都正確綁定post-construction,要模擬一個兼容的容器。這就有點可笑了,一個Date類需要一個容器來運行,但這確實是有害的注解對類、方法和參數的影響。

              無可否認,業務邏輯往往復雜,需要更多依賴和關系,而不僅僅是一個簡單的Date類。然而沒有理由在一個類中顯式或隱式地添加不必要的依賴或約束,有害的注解就是:依賴和約束。

              企業陷阱

              不幸的是有害的聲明在Java Enterprise 5大規模合法化。為了更正早期企業API的易用性問題,注解用來隱藏系統中冗余的和難用的部分。新的JEE 5被稱贊為”輕量級”和”簡單”,表面上看起來是這樣。但是一個微小的,同時也是至關重要的誤用蔓延開來。

              @Statelesspublic class DocumentRepository { public Document getDocument(String title) {

              ...

              }

              ...

              }

              如果想要獲取一個Stateless EJB,“只需要”在類上聲明@Stateless注解。確實,編寫這個類只需要只一點動作,但是請注意這個類中有害的注解綁定了幾百頁的說明文檔,而且只能在百萬字節的應用服務器(Application Server)上運行。這又怎么能稱的上是”輕量級”呢。所以,這個注解僅僅是真正需要編寫的Java代碼的占位符而已,代碼仍需要以某種形式存在。現在只不過是隱藏在注解之下。

              不幸的是,這種變通方案稱為一種模式,現在有害的注解廣泛分布:JPA, CDI, Common Annotations, JAXB 等等。

              有害的注解有時會出現在錯誤的地點

              因為注解通常作為開發環境,有時有害的注解被當做單一職責原則(Single Responsibility Principle)或關注點分離(Separation of Concerns)的最佳實踐。

              讓我們來考慮一下下面這個CDI例子:

              @ApplicationScopedpublic class DocumentFormatter {

              ...

              }

              上面的注解描述這個類應該是一個CDI Bean,意味著它應該只能由CDI實例化,并確保每個應用中只有一個實例。

              這些信息并不屬于這個類。這個服務在功能上(無論什么方式)并不會對它在當前應用中的作用產生影響。這里有兩個明顯的關注點。

              一個JPA的簡單例子:

              @Entity@Table("PERSON")public class Person {

              ...

              }

              問題在于這種類往往是”領域對象(domain objects)”,它們直接將領域模型持久化。更糟的是,數據傳送對象(DTO)用來在對象之間傳送數據,使得整個構造變得脆弱,因為對象間耦合過于緊密。不管怎樣,這是一種錯誤的方式。

              所有的這些附加的功能和(或)信息應該從這些類中分離出來,但是它們卻悄悄混在一起,因為它們”只不過”是注解。

              有害的注解有時蔓延

              注解有時會傳染其他對象。回顧上面那個CDI Bean。每個使用它的對象,每個依賴它的對象現在都擁有一個CDI注解,否則依賴關系樹就不會構建成功。

              @Entity注解也一樣。因為對象之間的關系,其他對象也通過注解持久化,很快所有的持久化對象都會有這個注解。我們無法使用原生的第三方對象(除非序列化或包裝它們),我們無法使用其他持久化機制(比如用NoSQL DB存放對象)。

              這些注解使得這些對象無法復用。它們只能在一個嚴格的、受控制的、不透明的環境中使用,不能和任何東西整合。

              有什么替代品?

              是XML嗎?當然不是,至少對于上面的例子來說不是。

              Spring框架使用配置來管理對象,因此可以用XML當做配置文件。然而,是否某個依賴需要在運行期改變,而不通過重新編譯?如果不需要,那么很難說配置應該用另一門語言來表示,尤其重構困難、測試困難、管理需要特殊工具。

              真正的替代品當然是好的Java代碼,正確封裝并解耦的。是的,用代碼來管理對象,盡管有時被當做樣板(boilerplate),但并不算糟糕。它帶來一些好處,比如讓代碼可讀、可調試、可重構。只有那些長片的、復雜的、冗余的樣板是糟糕的,比如“關于EJB 2.0”。但是解決方案并不是擺脫所有的樣板或用另一種語言隱藏樣板,而是簡單干凈的架構,直接而不多余的信息,簡單并合適的方式來面向對象。

              這也適用于JPA、Spring和其他東西。誤用注解來表示功能會發生Stcakoverflow上這個問題“Arguments Against Annotations”,為什么不用已有的工具呢:比如Java語言本身和編譯器,來解決這類問題,面向對象和軟件最佳實踐。

              如果注解在代碼運行期加上了額外功能和約束,那它是有害的。這很糟糕,因為它隱藏了類或方法的切面,使之難懂、難復用、難重構、難測試。

              不幸的是Java Enterprise不理睬Java開發者社區中發對注解的聲音。所以企業級Java和其他”官方”框架更不可能重視這類問題。

              至少我們可以持續關注有害的注解,如果可能盡量避免使用,編寫新的框架和軟件替換掉注解,不會出現有害注解所帶來的問題。

            【java的繼承與組合的區別】相關文章:

            Java中的繼承與組合01-28

            Java 繼承07-04

            java的繼承總結08-06

            Java與Java web的區別01-30

            Java語言繼承的要點03-13

            java繼承是什么06-11

            Java語言的繼承結構06-21

            java語言的接口與繼承02-26

            JavaScript與Java的區別03-30

                    <pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

                    <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

                    <p id="bbfd9"></p>

                    <p id="bbfd9"><cite id="bbfd9"></cite></p>

                      <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

                      <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
                      <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
                      飘沙影院