一、定義.
在面向對象的概念中,我們知道所有的對象都是通過類來描繪的,但是反過來卻不是這樣。並不是所有的類都是用來描繪對象的,如果一個類中沒有包含足夠的信息來描繪一個具體的對象,這樣的類就是抽象類。純虛函數是在基類中聲明的虛函數,它在基類中沒有定義,但要求任何派生類都要定義自己的實現方法。在基類中實現純虛函數的方法是在函數原型後加“=0”。[cpp] view plaincopyprint?virtual void funtion1()=0
virtual void funtion1()=0二、引入原因:
1、為了方便使用多態特性,我們常常需要在基類中定義虛擬函數。
2、在很多情況下,基類本身生成對象是不合情理的。例如,動物作為一個基類可以派生出老虎、孔雀等子類,但動物本身生成對象明顯不合常理。
為了解決上述問題,引入了純虛函數的概念,將函數定義為純虛函數,則編譯器要求在派生類中必須予以重載以實現多態性。同時含有純虛擬函數的類稱為抽象類,它不能生成對象。
三、相似概念:
1、多態性
指相同對象收到不同消息或不同對象收到相同消息時產生不同的實現動作。C++支持兩種多態性:編譯時多態性,運行時多態性。
a.編譯時多態性:通過重載函數實現
b 運行時多態性:通過虛函數實現。
2、虛函數
虛函數是在基類中被聲明為virtual,並在派生類中重新定義的成員函數,可實現成員函數的動態重載
3、抽象類
包含純虛函數的類稱為抽象類。由於抽象類包含了沒有定義的純虛函數,所以不能定義抽象類的對象。
四、程序
[cpp]
基類:
class A
{
public:
A();
void f1();
virtual void f2();
virtual void f3()=0;
virtual ~A();
};
子類:
class B : public A
{
public:
B();
void f1();
void f2();
void f3();
virtual ~B();
};
主函數:
int main(int argc, char* argv[])
{
A *m_j=new B();
m_j->f1();
m_j->f2();
m_j->f3();
delete m_j;
return 0;
}
基類:
class A
{
public:
A();
void f1();
virtual void f2();
virtual void f3()=0;
virtual ~A();
};
子類:
class B : public A
{
public:
B();
void f1();
void f2();
void f3();
virtual ~B();
};
主函數:
int main(int argc, char* argv[])
{
A *m_j=new B();
m_j->f1();
m_j->f2();
m_j->f3();
delete m_j;
return 0;
}
程序解釋:
f1()是一個普通的重載.
調用m_j->f1();會去調用A類中的f1(),它是在我們寫好代碼的時候就會定好的.
也就是根據它是由A類定義的,這樣就調用這個類的函數.
f2()是虛函數.
調用m_j->f2();會調用m_j中到底保存的對象中,對應的這個函數.這是由於new的B
對象.
f3()與f2()一樣,只是在基類中不需要寫函數實現.
五、總結
抽象就是把有共同屬性或方法的抽象成一個類實現不了自己定義的接口(純虛函數)就是抽象類。反過來想。如:我們定義了動物的類,屬性是有嘴,方法是 吃。我們沒有定義吃的具體實現。在派生類 老虎裡 定義了 吃的 具體實現 吃肉,派生類 牛 裡定義了 吃 的 具體實現 吃草,這就說明動物這個類 是抽象類,決定不了吃的具體實現,必須實現了吃 這個接口的類才不是抽象的類。如果實現了 吃的方法,那動物這個類就不能就不能通過接口說明 它是個抽象類。
定義純虛函數就是把派生類裡的共同的方法抽象出來放到基類裡,但並沒有具體實現(描述)(因為是抽象的無法具體描述對象),派生類裡對這些共同的方法來描述。如果一個類中沒有包含足夠的信息來描繪一個具體的對象,這樣的類就是抽象類。把’吃肉‘,’吃草‘的共同方法’吃‘提取出來,那麼動物就是抽象類。
將函數定義為純虛函數能夠說明,該函數為後代類型提供了可以覆蓋的接口,但是這個類中的版本決不會調用。
為什麼說只要擁有純虛函數的類就是抽象類?
派生類能夠描述對象的信息,而基類類卻不能描述此類對象的信息(即純虛函數),就是抽象類。
抽象類定義是對象有共同屬性或方法抽象成一個類,但無法描述具體的對象(肯定無法描述),它是不存在的
首先基類裡 存在著派生類的 共同的屬性 方法,但是如果是虛函數的話,基類的方法就和派生不一樣了,因為虛函數是動態綁定,它改寫基類的虛函數後,就與基類的實現不同了,這樣基類就沒有提取派生類的共同方法,基類也不是抽象類。如果定義為純虛函數,則基類的純虛函數就是個接口,純虛函數不能被調用,它的存在只是為了在派生類中重新定義。通過純虛函數的定義來確定抽象類以區別具體類。(同樣的方法因為派生類能夠調用而基類不能調用,所以是抽象類)抽象類也就是無法實例化。