1. 程式人生 > >C++虛擬函式與JAVA中抽象函式比較 介面與抽象類比較

C++虛擬函式與JAVA中抽象函式比較 介面與抽象類比較

C++虛擬函式與Java中抽象函式比較

1:java中沒有虛擬函式的概念,但是有抽象函式的概念,用abstract關鍵字表示,java中抽象函式必須在抽象類中,而且抽象 函式不能有函式體,抽象類不能被例項化,只能由其子類實現抽象函式,如果某個抽象類的子類仍是抽象類,那麼該子類不需要實現其父類的抽象函式。

2:C++中的有虛擬函式的概念,用virtual 關鍵字來表示,每個類都會有一個虛擬函式表,該虛擬函式表首先會從父類中繼承得到父類的虛擬函式表, 如果子類中重寫了父類的虛擬函式(不管重寫後的函式是否為虛擬函式),要呼叫哪個虛擬函式,是根據當前實際的物件來判斷的(不管指標所屬型別是否為當前類,有可 能是父型別),指標當前指向的是哪種型別的物件,就呼叫哪個型別中類定義的虛擬函式。每個類只有一張虛擬函式表,所有的物件共用這張表。 C++的函式多型就是通過虛擬函式來實現的。 3:C++中,如果函式不是虛擬函式,則呼叫某個函式,是根據當前指標型別來判斷的,並不是根據指標所指向物件的型別。
4:Java中,如果函式不是抽象函式,而是一個普通函式,它是預設實現類似C++中虛擬函式功能的,也就是說,呼叫某個函式,是根據當前指標所指向物件的型別來判斷的,而不是根據指標型別判斷。正好與C++中的普通函式相反。即:JAVA裡自動實現了虛擬函式。 C++                 Java
虛擬函式 -------- 普通函式
純虛擬函式 -------- 抽象函式
抽象類 -------- 抽象類
虛基類 -------- 介面

純虛擬函式: 主要特徵是不能被用來宣告物件,是抽象類,是用來確保程式結構與應用域的結構據具有直接對映關係的設計工具。帶有純虛擬函式的類稱為抽象類,抽象類能被子類 繼承使用,在子類中必須給出純虛擬函式的實現,如果子類未給出該純虛擬函式的實現,那麼該子類也是抽象類,只有在子類不存在純虛擬函式時,子類才可以用來宣告對 象!抽象類也能用於宣告指標或引用,或用於函式宣告中。具有抽象類特性的類還有建構函式和解構函式,全部是保護的類。如果沒有給出純虛擬函式的實現,則在它 所在的類的建構函式或解構函式中不能直接或間接的呼叫它。純虛擬函式的實現可以在類宣告外進行定義。

5. C++中一般都是把解構函式宣告為虛擬函式。因為虛擬函式可以實現動態繫結,也就是到底呼叫哪個函式是根據指標當前指向哪個物件來確定的,不是根據指標的型別來確定。如果C++中不把解構函式宣告為虛擬函式,那麼其有個子類,重寫了虛擬函式,那麼當父類指標指向一個子類物件時,當呼叫解構函式時,只調用父類的解構函式,而無法呼叫子類的解構函式,所以一般情況是把解構函式宣告為虛擬函式,實現動態繫結。當然如果一個類不包含虛擬函式,這經常預示不打算將它作為基類使用。當一個類不打算作為基類時,將解構函式宣告為虛擬通常是個壞主意。
標準 string 型別不包含虛擬函式,如果把String作為基類繼承得到子類會出問題。
總之:多型基類應該宣告虛解構函式。如果一個類有任何虛擬函式,它就應該有一個虛解構函式;如果不是設計用於做基類或不是設計用於多型,這樣的類就不應該宣告虛解構函式。

關於介面與抽象類:

      c++中沒有介面的概念,與之對應的是純虛類,即只含有純虛擬函式的類,c++抽象類的概念是含有純虛擬函式成員的類。這是因為c++提供多繼承,而像java、c#這些只提供單繼承(避免多繼承的複雜性和低效性)的語言為了模擬多繼承功能就提供了介面概念,介面可以繼承多個。

      abstract class是抽象類,至少包含一個純虛擬函式的類就叫做抽象類。

       但是如果一個類,所有的成員都是純虛擬函式,那麼它和一般的抽象類在用法上是有區別的。至少microsoft給的com介面定義全部都是僅由純虛擬函式構成的類。因此把這樣的類定義叫做純虛類也不算錯。

       純虛擬函式和虛擬函式的區別在於前者不包含定義,而後者包含函式體。

       那麼純虛類就是不包含任何實現(包括成員函式定義和成員變數定義。前者代表演算法,後者代表結構)。不包含任何演算法和結構的類叫做純虛類,應該沒有問題。

       在java裡面的確沒有純虛類的概念,因為java裡沒有純虛擬函式這個概念。java管虛擬函式叫做abstract function,管抽象類叫做abstract class,直接說來,java根本沒有virtual這個關鍵字,都用abstract代替,因此java裡面根本就沒有pure這個概念。有那就是interface。在interface裡面定義的函式都不能有函式體,這個在java裡面叫做介面。那麼c++裡面與interface等同的概念就是純虛類了,c++用純虛類來模擬interface這個抽象概念,因此這裡說的“純虛類”與java的abstract class不同,與c++的一般抽象類也不同。“純虛類”與c++一般抽象類的區別就好比java裡面interface 和 abstract class的區別。

    抽象類只能作為基類來使用,其純虛擬函式的實現由派生類給出。如果派生類中沒有重新定義純虛擬函式,而只是繼承基類的純虛擬函式,則這個派生類仍然還是一個抽象類。如果派生類中給出了基類純虛擬函式的實現,則該派生類就不再是抽象類了,它是一個可以建立物件的具體的類。

    抽象類是不能定義物件的。