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

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

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

2019-11-18 12:11:02
字體:
供稿:網(wǎng)友

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

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

圖片精選

主站蜘蛛池模板: 万盛区| 栖霞市| 天气| 稷山县| 碌曲县| 福海县| 湘乡市| 兴仁县| 彩票| 安化县| 山东省| 塘沽区| 泸州市| 武胜县| 九龙城区| 扎囊县| 清苑县| 昔阳县| 灌云县| 庆元县| 昆明市| 明光市| 疏勒县| 台山市| 陕西省| 清丰县| 稻城县| 华阴市| 凤冈县| 醴陵市| 五华县| 泾川县| 甘肃省| 江川县| 元朗区| 深圳市| 海晏县| 黄冈市| 昭苏县| 襄垣县| 沙洋县|