深入浅出之抽象与非抽象
一、虛函數&純需函數
虛函數?是在基類中使用關鍵字?virtual?聲明的函數。在派生類中重新定義基類中定義的虛函數時,會告訴編譯器不要靜態鏈接到該函數。
我們想要的是在程序中任意點可以根據所調用的對象類型來選擇調用的函數,這種操作被稱為動態鏈接,或后期綁定。
class Shape {protected:int width, height;public:Shape( int a=0, int b=0){width = a;height = b;}virtual int area(){cout << "Parent class area :" <<endl;return 0;} };純虛函數
您可能想要在基類中定義虛函數,以便在派生類中重新定義該函數更好地適用于對象,但是您在基類中又不能對虛函數給出有意義的實現,這個時候就會用到純虛函數。
virtual 返回值類型成員函數名(參數表)=0;
class Shape {protected:int width, height;public:Shape( int a=0, int b=0){width = a;height = b;}// pure virtual functionvirtual int area() = 0; };= 0 告訴編譯器,函數沒有主體,上面的虛函數是純虛函數。
虛函數和純虛函數有以下所示方面的區別。
(1)類里如果聲明了虛函數,這個函數是實現的,哪怕是空實現,它的作用就是為了能讓這個函數在它的子類里面可以被覆蓋,這樣的話,這樣編譯器就可以使用后期綁定來達到多態了。純虛函數只是一個接口,是個函數的聲明而已,它要留到子類里去實現。
(2)虛函數在子類里面也可以不重載的;但純虛函數必須在子類去實現,這就像Java的接口一樣。通常把很多函數加上virtual,是一個好的習慣,雖然犧牲了一些性能,但是增加了面向對象的多態性,因為很難預料到父類里面的這個函數不在子類里面不去修改它的實現。
(4)帶純虛函數的類叫虛基類,這種基類不能直接生成對象,而只有被繼承,并重寫其虛函數后,才能使用。這樣的類也叫抽象類。抽象類和大家口頭常說的虛基類還是有區別的,在C#中用abstract定義抽象類,而在C++中有抽象類的概念,但是沒有這個關鍵字。抽象類被繼承后,子類可以繼續是抽象類,也可以是普通類。
?二、抽象類
? ? ?包含純虛函數的類稱為抽象類。由于抽象類包含了沒有定義的純虛函數,所以不能定義抽象類的對象。
? ? ?在C++中,我們可以把只能用于被繼承而不能直接創建對象的類設置為抽象類(Abstract Class)。
? ? ?帶有純虛函數的類稱為抽象類。抽象類是一種特殊的類,它是為了抽象和設計的目的而建立的,它處于繼承層次結構的較上層。抽象類是不能定義對象的,在實際中為了強調一個類是抽象類,可將該類的構造函數說明為保護的訪問控制權限。
??? 抽象類的主要作用是將有關的組織在一個繼承層次結構中,由它來為它們提供一個公共的根,相關的子類是從這個根派生出來的。
??? 抽象類刻畫了一組子類的操作接口的通用語義,這些語義也傳給子類。一般而言,抽象類只描述這組子類共同的操作接口,而完整的實現留給子類。
??? 抽象類只能作為基類來使用,其純虛函數的實現由派生類給出。如果派生類沒有重新定義純虛函數,而派生類只是繼承基類的純虛函數,則這個派生類仍然還是一個 抽象類。如果派生類中給出了基類純虛函數的實現,則該派生類就不再是抽象類了,它是一個可以建立對象的具體類了。
抽象類的規定
(1)抽象類只能用作其他類的基類,不能建立抽象類對象。
(2)抽象類不能用作參數類型、函數返回類型或顯式轉換的類型。
(3)可以定義指向抽象類的指針和引用,此指針可以指向它的派生類,進而實現多態性。
class AbstractCalculator { public:virtual int getResult() = 0;virtual void setOperatorNumber(int a, int b) = 0;};//加法計算器類 一個類只做一件事 class PlusCalculator :public AbstractCalculator { public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA + mB;} public:int mA;int mB; };//減法計算器類 class MinuteCalculator :public AbstractCalculator { public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA - mB;} public:int mA;int mB; };//乘法計算器類 class MultiplyCalculator :public AbstractCalculator { public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA * mB;} public:int mA;int mB; };int main(void) {AbstractCalculator* caculator = new PlusCalculator;calculator->setOperatorNumber(10, 20);cout << calculator->getResult() << endl;delete calculator;return 0; }如果定義如下是錯誤的
AbstractCalculator* caculator = new AbstractCalculator; //錯誤三、抽象類與非抽象類?
抽象類與非抽象類的區別:
1、抽象類可以被繼承但不能被實例化(可以引用子類實例化對象),子類繼承自抽象類后必須實現該類的所有抽象方法;
2、抽象類中可以有抽象方法和非抽象方法,非抽象類不能有抽象方法,抽象方法一定要被子類重寫,而其他方法沒要求。
四、抽象類與接口
接口描述了類的行為和功能,而不需要完成類的特定實現。
C++ 接口是使用抽象類來實現的,抽象類與數據抽象互不混淆,數據抽象是一個把實現細節與相關的數據分離開的概念。
如果類中至少有一個函數被聲明為純虛函數,則這個類就是抽象類。純虛函數是通過在聲明中使用 "= 0" 來指定的,如下所示:
class Box {public:// 純虛函數virtual double getVolume() = 0;private:double length; // 長度double breadth; // 寬度double height; // 高度 };抽象類和接口的區別:
1、抽象類中可以有實現成員(非抽象方法),而接口中的方法只有聲明沒有實現;
2、抽象類中可以有字段,接口中不能有字段,但可以有屬性;
3、抽象類的成員可以使用公有或其他修飾符,接口中成員是隱式公有的,不需要修飾;
4、抽象類是概念的抽象,接口注重行為,抽象類不支持多重繼承,而一個類可以實現多個接口。
五、抽象方法
抽象方法,這種方法只聲明返回的數據類型,方法名稱和所需要的參數,沒有方法體,也就是說抽象方法只需要聲明而不需要事先,當一個方法為抽象方法時,意味著這個方法必須被子類的方法所重寫,否則其子類的該方法仍然是abstract的,而這個子類也必須是抽象的,即聲明為abstract。
?
參考
總結
以上是生活随笔為你收集整理的深入浅出之抽象与非抽象的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 江天路2号附2号一竹寿司为何总是关着门营
- 下一篇: 三人头像一男两女真人图片(三人头像一男两