国产99福利精品视频|杨幂精品国产福利在线|国精品午夜福利视频不卡|欧美精品黄网站在线播放|精品国产乱码久久久久久久|国产大片中文字幕在线观看|国产肥熟女视频一区二区三区|国产乱码无码视频一区二区三区

初學(xué)者:C++和java多態(tài)的區(qū)別

來源:北大青鳥飛迅校區(qū)|發(fā)布時間:2013-05-05 11:24:38

  C++中,如果父類中的函數(shù)前邊標(biāo)有virtual,才顯現(xiàn)出多態(tài)。

  如果父類func是virtual的,則

  Super *p =new Sub();

  p->func(); // 調(diào)用子類的func

  如果不是virtual的,p->func將調(diào)用父類原來的函數(shù)。

  Java中,不管寫不寫virtual都是多態(tài)的,子類的同名函數(shù)會override父類的。與C++很不同的是,初始化的過程也不相同。在還未初始化子類的時候,子類的同名函數(shù)就已經(jīng)覆蓋了父類的了。例如:

  public class Super {

  public Super() {

  System.out.println("super constructor...");

  m();

  }

  protected void m() {

  System.out.println("test");

  }

  }

  public class Sub extends Super{

  private final Date date;

  public Sub(){

  System.out.println("sub constructor...");

  date=new Date();}

  public void m()

  {

  System.out.println(date);

  }

  public static void main(String[] args)

  {

  Super test1=new Sub();

  test1.m(); //執(zhí)行的子類的m

  }

  }

  new Sub的時候首先調(diào)用Super,Super構(gòu)造函數(shù)調(diào)用的m就已經(jīng)是被Sub覆蓋的m,所以會print出null(因為日期沒有初始化)。所以在java中,不要在父類構(gòu)造函數(shù)中調(diào)用外部可改變的方法,有可能會輸出可改變方法中還沒初始化的東西。

  但是,同樣的初始化在C++中,初始化一個子類的時候,父類調(diào)用的m,是父類自己的m,不會調(diào)用子類的。

  ——————

  另外一個參考也很有用:http://7880.com/info/Article-51701560.html,如下:

  C++和java中多態(tài)機制的異同

  以前我有個錯誤的觀點:即使在C++和java中多態(tài)性的實現(xiàn)機制可能不同,但它們的表現(xiàn)形式應(yīng)該相同,也就是說如果代碼結(jié)構(gòu)相同,那么執(zhí)行結(jié)果也應(yīng)該相同?上屡c愿違,事情并不總是你想象中的那樣子。(在看下文以前,你最好先考慮一下這個問題,你有什么看法呢?)

  ok,讓我們進入正題。

  首先本文不討論面向?qū)ο缶幊痰幕靖拍,如封裝、繼承和數(shù)據(jù)抽象等,這方面的資料現(xiàn)在應(yīng)該多如牛毛,只是稍微提一下多態(tài)性的概念。根據(jù)Bjarne Stoustrup的說法,多態(tài)性其實就是方法調(diào)用的機制,也就是說當(dāng)在編譯時無法確定一個對象的實際類型時,應(yīng)當(dāng)能夠在運行時基于對象的實際類型來決定調(diào)用的具體方法(動態(tài)綁定)。

  我們先來看一下在C++中的函數(shù)調(diào)用方式:

  Ø 普通函數(shù)調(diào)用:具體調(diào)用哪個方法在編譯時間就可以決定(通過查找編譯器的符號表),同時在使用標(biāo)準(zhǔn)過程調(diào)用機制基礎(chǔ)上增加一個表示對象身份的指針(this指針)。

  Ø 虛函數(shù)調(diào)用:函數(shù)調(diào)用依賴于對象的實際類型,一般地說,對象的實際類型只能在運行時間才能確定。虛函數(shù)一般要有兩個步驟來支持,首先每一個類產(chǎn)生出一堆指向虛函數(shù)的指針,放在表格中,這個表格就叫虛函數(shù)表(virtual table);然后每一個類對象(class object)會添加一個指向相關(guān)虛函數(shù)表(virtual table)的指針,通常這個指針叫做vptr。

  在java中又是如何的呢?恩,區(qū)別還是滿大的。在java虛擬機中,類實例的引用就是指向一個句柄(handle)的指針,而該句柄(handle)其實是一對指針:其中一個指針指向一張表,該表格包含了對象的方法列表以及一個指向類對象(表示對象類型)的指針;另一個指針指向一塊內(nèi)存地址,該內(nèi)存是從java堆中為對象的數(shù)據(jù)而分配出來的。

  唔,你要說了,好象差不多嘛,不是都要維護一張函數(shù)表嗎?別急,讓我們先看一下例子,這樣你就能更好的理解它們之間的區(qū)別到底有多大了。

  下面是C++和java的例子,不看后面的答案,你能夠正確說出它們的執(zhí)行結(jié)果嗎?

  例1:C++

  class Base

  {

  public:

  Base()

  {

  init();

  }

  virtual ~Base() {}

  public:

  virtual void do_init()

  {

  init();

  }

  protected:

  virtual void init()

  {

  cout << "in Base::init()" << endl;

  }

  };

  class Derived : public Base

  {

  public:

  Derived()

  {

  init();

  }

  protected:

  void init()

  {

  cout << "in Derived::init()" << endl;

  }

  };

  int main(int argc, char* argv[])

  {

  Base* pb;

  pb = new Derived();

  delete pb;

  return 0;

  }

  例2:java

  class Base

  {

  public Base()

  {

  init();

  }

  protected void init()

  {

  System.out.println("in Base::init()");

  }

  public void do_init()

  {

  init();

  }

  }

  class Derived extends Base

  {

  public Derived()

  {

  init();

  }

  protected void init()

  {

  System.out.println("in Derived::init()");

  }

  }

  public class Test

  {

  public static void main(String[] args)

上一篇:新手如何開發(fā)出高質(zhì)量J2EE系統(tǒng)
下一篇:java面試必知的SQL語法及語句

熱門話題

招生熱線: 4008-0731-86 / 0731-82186801

學(xué)校地址: 長沙市天心區(qū)團結(jié)路6號

Copyright © 2006 | 湖南大計信息科技有限公司 版權(quán)所有

湘ICP備14017520號-3

關(guān)注我們
在線咨詢
嘿,我來幫您!