国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

JAVA的interface觀念與C++多重繼承的比較

2019-11-18 11:18:06
字體:
來源:轉載
供稿:網友

  作者:egreenworld
  
  依據DDJ的C/C++專欄作家Al Steven表示:他雖然不是很懂得java╋但是看到這些書中對于C++的物件導向概念的闡釋╋有些地方明顯錯誤╋真是令人擔心。本文假設讀者您已熟悉一些C/C++語言的概念╋對Java也有初步的熟悉。而談論Java的interface與C++的多重繼續之主要異同處。
  interface與多重繼續的觀念
   不管是Java的interface或是C++的多重繼續╋在物件導向的理論里╋都算是蠻新奇的概念。所以這里我們談的╋是以程式語言的角度╋看看Java interface的所有意義與功能╋是否C++的多重繼續能全部詮釋?或是相反地以Java的來詮釋C++的。
  
   首先讓我們來復習一下什么是C++的多重繼續。 「繼續」通常在物件導向程式語言中╋扮演著程式碼的重復利用的重責大任╋而C++的多重繼續則讓某一個子類別可以繼續許多分屬于不同資料型別的父類別如下:
  
  #include
  
  class Test1 {
  
  public:
  
   virtual void f1() {puts("Test1::f1()"); }
  
   virtual void g1() {puts("Test1::g1()"); }
  
  };
  
  class Test2 {
  
  public:
  
   virtual void f2() { puts("Test2::f2()"); }
  
   virtual void g2() { puts("Test2::g2()"); }
  
  };
  
  class Test3 : public Test1, public Test2 {
  
  public:
  
   virtual void gg() { puts("Test3::gg()"); }
  
  };
  
  void main() {
  
   Test3 t3; t3.f1(); t3.f2();
  
   t3.g1(); t3.g2(); t3.gg();
  
  }
  
  // 程式輸出:
  
  Test1::f1() Test2::f2() Test1::g1()
  
  Test2::g2() Test3::gg()
  
  程式1?C++的多重繼續
  
   根據[Rie96]╋認為正確使用物件導向技術中之「多重繼續」觀念╋應該如下面的例子:
  
   假設有一個木造門╋則:
  
  1. 此木造門是門的一種(a kind of)。
  
  2. 但門不是木造門的一部份(a part of)。
  
  3. 木造門是木制品的一種。
  
  4. 但木制品不是木造門的一部份。
  
  5. 木制品不是門的一種。
  
  6. 門也不是木制品的一種。
  
   所以您可以發現╋多重繼續在使用時╋必須非常小心╋而且在許多時候╋其實我們并不需要多重繼續的。
  
   Java也提供繼續機制╋但還另外提供一個叫interface的概念。由于Java的繼續機制只能提供單一繼續(就是只能繼續一種父類別)╋所以就以Java的interface來代替C++的多重繼續。interface就是一種介面╋規定欲溝通的兩物件╋其通訊該有的規范有哪些。如以Java程式語言的角度來看╋Java的interface則表示:一些函數或資料成員╋為另一些屬于不同類別的物件所需共同擁有╋則將這些函數與資料成員╋定義在一個interface中╋然后讓所有不同類別的Java物件可以共同操作使用之。
  
   所以╋對于Java的繼續與interface╋我們總結如下:
  
  1.Java的class只能繼續一個父類別(用extends要害字)╋但可以擁有(或稱實作)許多interface(用implements要害字)。
  
  2.Java的interface可以繼續許多別的interface(也是用extends要害字)╋但不可以實作任何interface。
  
   因此╋我們可以利用Java的interface來模擬C++的多重繼續。如上面的例子可以轉化如下:
  
  interface Test1 {
  
   public void f1();
  
   public void g1();
  
  }
  
  interface Test2 {
  
   public void f2();
  
   public void g2();
  
  }
  
  interface Test3 extends Test1, Test2 {
  
   public void gg();
  
  }
  
  class CTest implements Test3 {
  
   public void f1() { System.out.  
   public void g1() { System.out.println("Test1::g1()"); }
  
   public void f2() { System.out.println("Test2::f2()"); }
  
   public void g2() { System.out.println("Test2::g2()"); }
  
   public void gg() { System.out.println("Test3::gg()"); }
  
  }
  
  class Run {
  
   public void run() {
  
   CTest ct=new CTest(); ct.f1();ct.f2();
  
   ct.g1();ct.g2(); ct.gg();
  
   }}
  
  class Main {
  
   public static void main (String args[]) {
  
   Run rr=new Run();
  
   rr.run();
  
   }}
  
  // 程式輸出:
  
  Test1::f1() Test2::f2() Test1::g1()
  
  Test2::g2() Test3::gg()
  
  程式2?利用Java的interface完成C++的多重繼續功能
  
  然而╋根據[Ait96]的文章顯示╋他認為Java的interface比C++的多重繼續好學很多╋也較輕易懂╋但是有其限制。對于Java interface的易懂╋在文章中╋并沒有說明。其主要即為「介面繼續」與「實作繼續」概念的差異。
  
   「介面繼續」就是只繼續父類別的函數名稱╋然后子類別一定會實作取代之。所以當我們以父類別的指標「多型」于各子類別時╋由于子類別一定會實作父類別的多型函數╋所以每個子類別的實作都不一樣╋此時我們(使用父類別指標的人)并不知道此多型函數到底怎么完成╋因之稱為「黑箱設計」。
  
   「實作繼續」就是繼續父類別的函數名稱╋子類別在實作時╋也會用到父類別的函數實作。所以我們(使用父類別指標的人)知道此多型函數怎么完成工作╋因為大概也跟父類別的函數實作差不多╋因之稱為「白箱設計」。
  
   套用的Java的interface上╋我們發現╋Java的interface就是介面繼續╋因為Java interface只能定義函數名稱╋無法定義函數實作╋所以子類別必須用「implements」要害字來實作之╋且每個實作同一介面的子類別當然彼此不知道對方如何實作╋因此為一個黑箱設計。
  
   Java的類別繼續則為實作繼續╋子類別會用到父類別的實作(更正確地說應該是父類別有定義實作╋所以子類別可能會使用到╋即使不使用到也會遵循父類別實作的演算法)╋所以父類別與子類別有一定程度的相關性?不像介面繼續╋彼此只有函數名字剛好一樣而已。
  
   介面繼續與實作繼續╋應對至Java的interface?class?extends與implements要害字╋很輕易了解其含意。但是C++的繼續機制╋似乎就沒有那么輕易解釋清楚的!所以這就是[Ait86]文章中所表示的意思:C++多重機制比較復雜。
  
   所以接下來我們將討論:
  
  C++的多重繼續有什么功能╋是Java的interface所達不到的?
   在C++的ARM中╋或是[Str94]的多重繼續章節里╋皆提到了下述聞名的例子:
  
  #include
  
  class t1 {
  
  public:
  
   virtual void f() { puts("t1::f()"); }
  
   virtual void g() { puts("t1::g()"); }
  
  };
  
  class t2 : public virtual t1 {
  
  public:
  
   virtual void g() { puts("t2::g()"); }
  
  };
  
  class t3 : public virtual t1 {
  
  public:
  
   virtual void f() { puts("t3::f()"); }
  
  };
  
  class t4 : public t2, public t3, public virtual t1 { ...};
  
  void main() {
  
  t4 *tt4=new t4; t2 *tt2=tt4; t3 *tt3=tt4;
  
  tt4->f(); tt4->g(); tt2->f(); tt3->g();
  
  }
  
  // 程式輸出:
  
  t3::f() t2::g() t3::f() t2::g()
  
  程式3?C++聞名的環狀繼續
  
   由上例╋我們發現╋C++的多重繼續具有下列兩個特質是Java的interface所不能達到的功能。
  
  圖1?C++的環狀多重繼續
  
  C++的多重繼續可以形成環狀繼續關系╋如圖1。但是不管是Java的繼續機制或是interface╋都不容許有環狀的情況發生。換句話說╋因為C++有virtual base的屬性的父類別╋所有在多重繼續時╋答應父類別被繼續兩次以上。但Java則完全不行。
  
   本題中的tt4指標╋轉成tt2指標后╋執行f()函數時╋仍然會正確地執行tt4中的f()函數╋也就是t3::f()。我們可以發現╋這種找函數的方式╋是先找函數的正確名稱╋再找函數所屬的類別的正確名稱。與Java的虛擬函數(或稱為abstract函數)不同。Java的是先找指標(或參考)所屬的正確類別名稱╋再繼續找類別名稱下的正確函數名稱。
  
  圖2?對于虛擬函數C++與Java的各別作法
  
   對于第二點參考圖2。C++的虛擬函數╋可以參考[Sou94]╋C++編譯器對于每一個虛擬函數╋均建立一個虛擬函數表與之應對╋因為每一個虛擬函數在一個繼續樹可能有許多子類別實作之。因

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 合江县| 河源市| 邛崃市| 菏泽市| 梅河口市| 深泽县| 资溪县| 南乐县| 犍为县| 勐海县| 丹凤县| 遵义市| 东兴市| 资中县| 陆川县| 九台市| 竹北市| 定安县| 大连市| 伊宁市| 广德县| 大埔区| 山东省| 佛学| 华容县| 固阳县| 屏南县| 剑阁县| 定边县| 兴和县| 大石桥市| 隆回县| 伊春市| 通化市| 鸡泽县| 方山县| 固原市| 息烽县| 南宫市| 阿拉善盟| 崇文区|